Python-将多列拆分为多行

Python-将多列拆分为多行,python,python-3.x,pandas,Python,Python 3.x,Pandas,我试图在几行中将多列拆分为多行,而不是为其编写一个大的“def函数”。 我有两列需要按拆分。我试着这样做: #错误:value错误:数组的长度必须相同 寻找如下输出: 产品在这里更合适: import itertools def splitter(values): return list(itertools.product( *[str(v).split(';') for v in values])) In [6]: splitter(df.iloc[2]) #example Out

我试图在几行中将多列拆分为多行,而不是为其编写一个大的“def函数”。 我有两列需要按
拆分。我试着这样做:

#错误:value错误:数组的长度必须相同

寻找如下输出:

产品在这里更合适:

import itertools

def splitter(values):
    return list(itertools.product( *[str(v).split(';') for v in values]))

In [6]: splitter(df.iloc[2]) #example
Out[6]: 
[('g', '15', 'pinneapple'),
 ('e', '15', 'pinneapple'),
 ('a', '15', 'pinneapple')]
现在,对所有行执行此操作并重建新的数据帧:

def expand(df):
    tuples=list()
    for i,row in df.iterrows():
        tuples.extend(splitter(row))
    return  pd.DataFrame.from_records(tuples,columns=df.columns)
结果:

In [7]: expand(df)
   var  var2        var3
0     a    1      apples
1     a    1       mango
2     b    1      apples
3     b    1       mango
4     c    1      apples
5     c    1       mango
6     d    2        kiwi
7     d    2   pineapple
8     e    2        kiwi
9     e    2   pineapple
10    f    2        kiwi
11    f    2   pineapple
12    g   15  pinneapple
13    e   15  pinneapple
14    a   15  pinneapple
15    m   12      orange

请尝试以下代码:

import pandas as pd

# Source data
a = pd.DataFrame([{'var1': 'a;b;c', 'var2': 1,'var3':'apples;mango'},
    {'var1': 'd;e;f', 'var2':  2,'var3':'kiwi;pineapple'},
    {'var1': 'g;e;a', 'var2': 15,'var3':'pinneapple'},
    {'var1': 'm',     'var2': 12,'var3':'orange'}])
# Split var1
a2 = a.var1.apply(lambda t: pd.Series(t.split(';')))\
    .merge(a, right_index = True, left_index = True)\
    .drop(['var1'], axis = 1)\
    .melt(id_vars = ['var2', 'var3'], value_name = 'var1')\
    .drop('variable', axis = 1).dropna()
# Split var3
a3 = a2.var3.apply(lambda t: pd.Series(t.split(';')))\
    .merge(a2, right_index = True, left_index = True)\
    .drop(['var3'], axis = 1)\
    .melt(id_vars = ['var1', 'var2'], value_name = 'var3')\
    .drop('variable', axis = 1).dropna()
# Sort the result
a3.sort_values(['var2', 'var3'])
a2
包含一个将
var1
划分为单独行的表

var3的相同操作执行下一条指令(类似于
前一个名称已更改

最后一步是对结果进行排序

要了解此代码的工作原理,请分别执行每个步骤 其中一个链接指令的

如果要划分的列更多,请添加类似的“拆分”
有关它们的说明。

在每列上使用
str.split
stack
后,可以
连接每列。这可以通过首先定义一个函数来实现,以使列具有正确的形状:

def split_stack_col (a_col):
    return (a_col.astype(str).str.split(';',expand=True).stack()
                 .reset_index(level=1,name=a_col.name)[[a_col.name]])
然后,在将
reduce
与join一起使用之前,您将
map
此函数映射到每一列。如果需要,请添加一个reset\u索引

from functools import reduce
new_df = reduce(lambda x,y: x.join(y), 
                map( split_stack_col, 
                     (a[col] for col in a.columns))).reset_index(drop=True)
此方法可用于
a
中任意数量的列,您可以得到预期的结果:

print (new_df)
   var1 var2        var3
0     a    1      apples
1     a    1       mango
2     b    1      apples
3     b    1       mango
4     c    1      apples
5     c    1       mango
6     d    2        kiwi
7     d    2   pineapple
8     e    2        kiwi
9     e    2   pineapple
10    f    2        kiwi
11    f    2   pineapple
12    g   15  pinneapple
13    e   15  pinneapple
14    a   15  pinneapple
15    m   12      orange

您尝试的解决方案的主要区别在于,您需要
var1
var3
中的值的笛卡尔积(例如,第一行在输出中有3*2行),而解决方案是在
包中的任何值与
包中的一个值关联时编写的。
print (new_df)
   var1 var2        var3
0     a    1      apples
1     a    1       mango
2     b    1      apples
3     b    1       mango
4     c    1      apples
5     c    1       mango
6     d    2        kiwi
7     d    2   pineapple
8     e    2        kiwi
9     e    2   pineapple
10    f    2        kiwi
11    f    2   pineapple
12    g   15  pinneapple
13    e   15  pinneapple
14    a   15  pinneapple
15    m   12      orange