2017-04-17 68 views
2

我有一个数据帧拆分设置为多列大熊猫的Python

 IDs   Types 
0  1001   {251} 
1  1013  {251, 101} 
2  1004  {251, 701} 
3  3011   {251} 
4  1014   {701} 
5  1114   {251} 
6  1015   {251} 

其中df['Types']具有组,每个组一行。我想这列转换为多列,这样我可以得到下面的输出

 IDs Type1 Type2 
0  1001  251  - 
1  1013  251  101 
2  1004  251  701 
3  3011  251  - 
4  1014  701  -  
5  1114  251  - 
6  1015  251  - 

目前,我使用下面的代码来实现这一

pd.concat([df['Types'].apply(pd.Series), df['IDs']], axis = 1) 

但它返回下面的错误

Traceback (most recent call last): 
    File "C:/Users/PycharmProjects/test/test.py", line 48, in <module> 
    df = pd.concat([df['Types'].apply(pd.Series), df['IDs']], axis = 1) 
    File "C:\Python\Python35\lib\site-packages\pandas\core\series.py", line 2294, in apply 
    mapped = lib.map_infer(values, f, convert=convert_dtype) 
    File "pandas\src\inference.pyx", line 1207, in pandas.lib.map_infer (pandas\lib.c:66124) 
    File "C:\Python\Python35\lib\site-packages\pandas\core\series.py", line 223, in __init__ 
    "".format(data.__class__.__name__)) 
TypeError: 'set' type is unordered 

请指导我如何获得所需的输出。谢谢

回答

1

我认为你需要首先构造函数DataFrame,然后重命名列和最后fillna

但是,如果使用fillna与一些字符串,它可能是问题,因为与字符串(-)混合数字和一些熊猫功能可以被打破。

df1 = pd.DataFrame(df['Types'].values.tolist()) \ 
     .rename(columns = lambda x: 'Type{}'.format(x+1)) \ 
     .fillna('-') 
print (df1) 
    Type1 Type2 
0 251  - 
1 251 101 
2 251 701 

df2 = pd.concat([df['IDs'], df1], axis = 1) 
print (df2) 
    IDs Type1 Type2 
0 1001 251  - 
1 1013 251 101 
2 1004 251 701 

另一个slowier解决方案:

df1 = df['Types'].apply(lambda x: pd.Series(list(x))) \ 
       .rename(columns =lambda x: 'Type{}'.format(x+1)) \ 
       .fillna('-') 

df2 = pd.concat([df['IDs'], df1], axis = 1) 
print (df2) 
    IDs Type1 Type2 
0 1001 251.0  - 
1 1013 251.0 101 
2 1004 251.0 701 
+0

感谢。我在想为什么我需要把这个集合转换成列表? – muazfaiz

+0

我不确定,但这个解决方案更快,因为'.apply(Series)',但'.apply(lambda x:pd.Series(list(x)))'可以工作。 – jezrael

2

这应该工作:

temp = pd.DataFrame(df.Types.values.tolist()).add_prefix('Types_').fillna('-').rename(columns={'Types_0':'Type1','Types_1':'Type2'}) 

df = pd.concat([df.drop('Types',axis=1), temp], axis=1) 

    IDs Types_0 Types_1 
0 1001  251  NaN 
1 1013  251 101.0 
2 1001  251 701.0 

编辑:我错过了('-')缺失值,现在应该是不错的。

EDIT2:列名@jezrael指出

+0

我认为你的输出与OP想要的有些不同,请检查它。 – jezrael

+0

我觉得'Types_0 Types_1' – jezrael

+0

你是对的。我会简单地使用'重命名'的约定,我会改变我的,但你的答案已经提供了这个:竖起大拇指: –

0

另一种方法:

df['Type1'] = df['Types'].apply(lambda x: list(x)[0]) 
df['Type2'] = df['Types'].apply(lambda x: list(x)[1] if len(x) > 1 else '-') 
0

一个衬垫(非常类似于@DmitryPolonskiy's solution):

In [96]: df.join(pd.DataFrame(df.pop('Types').values.tolist(), index=df.index) 
        .add_prefix('Type_')) \ 
      .fillna('-') 
Out[96]: 
    IDs Type_0 Type_1 
0 1001  251  - 
1 1013  251 101 
2 1004  251 701