Python 将数据帧中具有多个值的单元格转换为多行
我的数据如下:Python 将数据帧中具有多个值的单元格转换为多行,python,pandas,Python,Pandas,我的数据如下: Name test1 test2 Count Emp1 X,Y A 1 Emp2 X A,B,C 2 Emp3 Z C 3 我正在使用下面的代码将具有多个值的test1单元格拆分为单独的行。但是,我不确定如何拆分Test2列 df2 = df.test1.str.split(',').apply(pd.Series) df2.index
Name test1 test2 Count
Emp1 X,Y A 1
Emp2 X A,B,C 2
Emp3 Z C 3
我正在使用下面的代码将具有多个值的test1单元格拆分为单独的行。但是,我不确定如何拆分Test2列
df2 = df.test1.str.split(',').apply(pd.Series)
df2.index = df.set_index(['Name', 'count']).index
df2.stack().reset_index(['Name', 'count'])
df2
输出为:
Name test1 Count
Emp1 X 1
Emp1 Y 1
Emp2 X 2
Emp2 X 2
Emp2 X 2
Emp2 Z 3
我正在尝试拆分test1和test2,以便实现以下输出:
Name test1 test2 Count
Emp1 X A 1
Emp1 Y A 1
Emp2 X A 2
Emp2 X B 2
Emp2 X C 2
Emp2 Z C 3
有人能帮忙吗?我只是修复你的代码,因为我不推荐你卸载数据帧的方法,你可以在这里检查,有多种好方法
df2 = df.test1.str.split(',').apply(pd.Series)
df2.index = df.set_index(['Name', 'Count']).index
df2=df2.stack().reset_index(['Name', 'Count'])
df3 = df.test2.str.split(',').apply(pd.Series)
df3.index = df.set_index(['Name', 'Count']).index
df3=df3.stack().reset_index(['Name', 'Count'])
只需在这里进行merge
我认为适应这个问题并不是那么简单,所以我将提出一个解决方案 您可以创建一个函数,该函数采用
df
、一个要展开的列和该列的分隔符,并根据需要多次进行链调用
def expand(df, col, sep=','):
r = df[col].str.split(sep)
d = {c: df[c].values.repeat(r.str.len(), axis=0) for c in df.columns}
d[col] = [i for sub in r for i in sub]
return pd.DataFrame(d)
expand(expand(df, 'test1'), 'test2')
Name test1 test2 Count
0 Emp1 X A 1
1 Emp1 Y A 1
2 Emp2 X A 2
3 Emp2 X B 2
4 Emp2 X C 2
5 Emp3 Z C 3
假设你有一个
df['test3'] = ['X1|X2|X3', 'X4', 'X5']
以致
>>> print(df)
Name test1 test2 Count test3
0 Emp1 X,Y A 1 X1|X2|X3
1 Emp2 X A,B,C 2 X4
2 Emp3 Z C 3 X5
那么
如果您认为列的大小可能会大幅增加,则可以定义一个函数expand_all
,以避免出现类似expand(expand(expand)(expand(…..)!)))
的情况。例如:
def expand_all(df, cols, seps):
ret = df
for c,s in zip(cols,seps): ret = expand(ret,c,s)
return ret
>>> expand_all(df, ['test1', 'test2', 'test3'], [',', ',', '|'])
Name test1 test2 Count test3
0 Emp1 X A 1 X1
1 Emp1 X A 1 X2
2 Emp1 X A 1 X3
3 Emp1 Y A 1 X1
4 Emp1 Y A 1 X2
5 Emp1 Y A 1 X3
6 Emp2 X A 2 X4
7 Emp2 X B 2 X4
8 Emp2 X C 2 X4
9 Emp3 Z C 3 X5
或无论如何合适;)
详情:
>>> expand(df, 'test1')
Name test1 test2 Count
0 Emp1 X A 1
1 Emp1 Y A 1
2 Emp2 X A,B,C 2
3 Emp3 Z C 3
>>> expand(df, 'test2')
Name test1 test2 Count
0 Emp1 X,Y A 1
1 Emp2 X A 2
2 Emp2 X B 2
3 Emp2 X C 2
4 Emp3 Z C 3
>>> expand(expand(df, 'test2'), 'test1')
Name test1 test2 Count
0 Emp1 X A 1
1 Emp1 Y A 1
2 Emp2 X A 2
3 Emp2 X B 2
4 Emp2 X C 2
5 Emp3 Z C 3
>>> expand(expand(df, 'test2'), 'test1').eq(expand(expand(df, 'test1'), 'test2')).all()
Name True
test1 True
test2 True
Count True
dtype: bool
理解力
@Mahesh我试图使我的解决方案尽可能普遍化。稍后查看,看看是否有帮助;)@RafaelC我尝试了你建议的expand_all函数,我发现它正在扩展已经扩展的列。这导致了价值观的重复
def expand_all(df, cols, seps):
ret = df
for c,s in zip(cols,seps): ret = expand(ret,c,s)
return ret
>>> expand_all(df, ['test1', 'test2', 'test3'], [',', ',', '|'])
Name test1 test2 Count test3
0 Emp1 X A 1 X1
1 Emp1 X A 1 X2
2 Emp1 X A 1 X3
3 Emp1 Y A 1 X1
4 Emp1 Y A 1 X2
5 Emp1 Y A 1 X3
6 Emp2 X A 2 X4
7 Emp2 X B 2 X4
8 Emp2 X C 2 X4
9 Emp3 Z C 3 X5
>>> expand(df, 'test1')
Name test1 test2 Count
0 Emp1 X A 1
1 Emp1 Y A 1
2 Emp2 X A,B,C 2
3 Emp3 Z C 3
>>> expand(df, 'test2')
Name test1 test2 Count
0 Emp1 X,Y A 1
1 Emp2 X A 2
2 Emp2 X B 2
3 Emp2 X C 2
4 Emp3 Z C 3
>>> expand(expand(df, 'test2'), 'test1')
Name test1 test2 Count
0 Emp1 X A 1
1 Emp1 Y A 1
2 Emp2 X A 2
3 Emp2 X B 2
4 Emp2 X C 2
5 Emp3 Z C 3
>>> expand(expand(df, 'test2'), 'test1').eq(expand(expand(df, 'test1'), 'test2')).all()
Name True
test1 True
test2 True
Count True
dtype: bool
pd.DataFrame(
[(n, a, b, c)
for n, A, B, c in zip(*map(df.get, df))
for a in A.split(',') for b in B.split(',')],
columns=df.columns
)
Name test1 test2 Count
0 Emp1 X A 1
1 Emp1 Y A 1
2 Emp2 X A 2
3 Emp2 X B 2
4 Emp2 X C 2
5 Emp3 Z C 3