分割pandas dataframe行时出现问题?

时间:2016-12-20 14:34:37

标签: python python-3.x pandas dataframe

我有以下pandas数据帧:

在:

df

出:

         A    B        C                                             D
0  0938320  usa   amazon              orange: $ 8.00| pineapple: $2.00
1  0938320  usa  alibaba                  orange: $ 8.00| apple: $2.00
2  0938320  usa     ebay  mint: $ 8.00| watermelon: $2.00| mint: $2.00
...
n  0938320  usa   amazon                  pear: $ 8.00| bannana: $2.00

我想按|拆分并将其堆叠成(*):

         A    B        C                  D
0  0938320  usa   amazon     orange: $ 8.00
1  0938320  usa   amazon   pineapple: $2.00
2  0938320  usa  alibaba     orange: $ 8.00
3  0938320  usa  alibaba       apple: $2.00
4  0938320  usa      bay       mint: $ 8.00
5  0938320  usa     ebay  watermelon: $2.00
6  0938320  usa     ebay        mint: $2.00
7  0938320  usa   amazon       pear: $ 8.00
...
8  0938320  usa   amazon     bannana: $2.00

所以,我尝试了以下内容:

在:

s = df2.D.str.split("|").apply(pd.Series, 1).stack()
s.index = s.index.droplevel(-1)
del df2['D']
df.join(s)

出:

ValueError: Other Series must have a name

b = pd.DataFrame(df2.D.str.split('|').tolist(), index=df2['A','B','C']).stack()
b = b.reset_index()[[0, 'D']] 
b.columns = ['A','B','C']
b

但是,不起作用。如何修改最后一种方法才能得到(*)?我想我的主要问题是我不知道如何取index=df2['A','B','C']).stack()中的所有列。

2 个答案:

答案 0 :(得分:1)

您可以先将3列设置为DF的索引,然后在第4列D上执行拆分。让获得的输出采用str.split中的expand=True参数的数据帧形式。

In [55]: df
Out[55]: 
        A     B         C                                              D
0  938320   usa    amazon               orange: $ 8.00| pineapple: $2.00
1  938320   usa   alibaba                   orange: $ 8.00| apple: $2.00
2  938320   usa      ebay   mint: $ 8.00| watermelon: $2.00| mint: $2.00

In [56]: df_split = df.set_index(['A', 'B', 'C'])['D'].str.split('|', expand=True)

In [57]: df_split
Out[57]: 
                                    0                   1             2
A      B    C                                                          
938320  usa  amazon    orange: $ 8.00    pineapple: $2.00          None
             alibaba   orange: $ 8.00        apple: $2.00          None
             ebay        mint: $ 8.00   watermelon: $2.00   mint: $2.00

然后,stack他们获取一个健全的列(默认情况下丢弃NaNs),然后使用reset_index重新排列。

In [58]: df_split.stack().reset_index(level=[0,1,2], name='D').reset_index(drop=True)
Out[58]: 
        A     B         C                   D
0  938320   usa    amazon      orange: $ 8.00
1  938320   usa    amazon    pineapple: $2.00
2  938320   usa   alibaba      orange: $ 8.00
3  938320   usa   alibaba        apple: $2.00
4  938320   usa      ebay        mint: $ 8.00
5  938320   usa      ebay   watermelon: $2.00
6  938320   usa      ebay         mint: $2.00

答案 1 :(得分:1)

以下是使用join组合拆分数据的替代方法。

# split D and get it into long/stacked format
productsLong = pd.DataFrame({'products':
                df['D'].str.split('|', expand=True).stack().reset_index(level=1, drop=True)})

# join the data together on the indices
df[['A', 'B', 'C']].join(productsLong)

Out[56]: 
        A    B        C            products
0  938320  usa   amazon      orange: $ 8.00
0  938320  usa   amazon    pineapple: $2.00
1  938320  usa  alibaba      orange: $ 8.00
1  938320  usa  alibaba        apple: $2.00
2  938320  usa     ebay        mint: $ 8.00
2  938320  usa     ebay   watermelon: $2.00
2  938320  usa     ebay         mint: $2.00
3  938320  usa   amazon        pear: $ 8.00
3  938320  usa   amazon      bannana: $2.00

注释
rename方法返回错误,因此我将Series转换为DataFrame以提供列名。级别= 1的reset_index会删除"外部" index,保留原始DataFrame的索引(为连接操作正确重复)。