2017-10-02 2 views
0

Je concatène une série sur une trame de données, mais le nom de la colonne (nom de la série) n'apparaît pas sur la nouvelle trame de données. À la place, la colonne a le nom '0' dans la dernière image, mais pendant qu'elle est faite dans la méthode apply_join, le nom apparaît.Nom de la série Pandas n'apparaissant pas dans une base de données

Pourquoi le nom de la série n'est-il pas visible dans la base de données?

import pandas as pd 
from io import StringIO 

tibble3_csv = """country,year,cases,population 
Afghanistan,1999,745,19987071 
Afghanistan,2000,2666,20595360""" 
with StringIO(tibble3_csv) as fp: 
    tibble3 = pd.read_csv(fp) 

def str_join_elements(x, sep=""): 
    assert type(sep) is str 
    return sep.join((str(xi) for xi in x)) 

def unite(df, cols, new_var, combine=str_join_elements): 
    def apply_join(x, combine): 
     joinstr = combine(x) 
     ser = pd.Series(joinstr, name=new_var) 
     print(ser.name) 
     return ser 

    fixed_vars = df.columns.difference(cols) 
    tibble = df[fixed_vars].copy() 
    tibble_extra = df[cols].apply(apply_join, combine=combine, axis=1) 

    return pd.concat([tibble, tibble_extra], axis=1) 

tab = unite(tibble3, ['cases', 'population'], 'rate', combine=lambda x: str_join_elements(x, "/")) 
print(tab) 

Résultat:

rate 
rate 
     country year     0 
0 Afghanistan 1999  745/19987071 
1 Afghanistan 2000  2666/20595360 

Répondre

0

Si vous essayez de concaténer un nombre inconnu de colonnes, vous pouvez utiliser apply avec str.join:

def foo(df, columns, col_name, sep=''): 
    s = df[columns].apply(lambda x: sep.join(map(str, x)), 1) 
    s.name = col_name 
    return pd.concat([df[df.columns.difference(columns)], s], axis=1) 

df 
     country year cases population 
0 Afghanistan 1999 745 19987071 
1 Afghanistan 2000 2666 20595360 

df2 = foo(df, ['cases', 'population'], 'rate', '/') 
df2 
     country year   rate 
0 Afghanistan 1999 745/19987071 
1 Afghanistan 2000 2666/20595360 

Si ça va toujours Pour être deux colonnes, vous pouvez utiliser str.cat, c'est beaucoup plus rapide.

def foo2(df, c1, c2, c3, sep=''): 
    s1, s2 = df[c1].astype(str), df[c2].astype(str) 
    s3 = s1.str.cat(s2, sep=sep) 
    s3.name = c3 
    return pd.concat([df[df.columns.difference([c1, c2])], s3], axis=1) 

df2 = foo2(df, 'cases', 'population', 'rate', '/') 
df2 
     country year   rate 
0 Afghanistan 1999 745/19987071 
1 Afghanistan 2000 2666/20595360 
+0

J'aime votre solution simple. C'est une affectation cependant, et la signature de méthode de "foo/unite" inclut une fonction qui est passée, "combine" dans ce cas. – cumin

+0

@cumin Eh bien, il suffit d'utiliser 'tibble_extra.name = 'rate'' avant d'appeler' pd.concat'. :/ –

+0

@cumin La raison pour laquelle votre colonne de données d'origine n'a pas la colonne nommée est parce que le résultat de 'tibble_extra' n'a pas de nom. Vous devez en assigner un. Ce nom deviendra partie de la sortie df plus tard. –

0

Vous pouvez également essayer simplement de renommer la colonne à l'aide

>>> tab = tab.rename(columns = {0:'cases/population'}) 
>>> tab 
     country year cases/population 
0 Afghanistan 1999  745/19987071 
1 Afghanistan 2000 2666/20595360 
>>> 
+0

Merci, cela fonctionnera. Mais pourquoi le nom de la colonne ("rate") n'apparaît-il pas dans la df quand il apparaît quand la série est faite à 'print (ser.name)'? – cumin