Python-将多列拆分为多行
我试图在几行中将多列拆分为多行,而不是为其编写一个大的“def函数”。 我有两列需要按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
拆分代码>。我试着这样做:
#错误: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