拆分设置为多个列Pandas Python

时间:2017-04-17 14:40:01

标签: python pandas dataframe

我有一个数据框

        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

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

4 个答案:

答案 0 :(得分:2)

我认为您首先需要DataFrame构造函数,然后重命名列并持续fillna

但是如果将fillna与某些字符串一起使用,则可能会出现问题,因为混合数字与字符串(-)数据和一些pandas函数可能会被破坏。

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

另一个更慢的解决方案:

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

答案 1 :(得分: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的列名指出

答案 2 :(得分: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 '-')

答案 3 :(得分: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