将单个DataFrame行分解为多个行



My DataFrame有一些列,其中每个值都可以是"1〃"2〃"3〃;或";任何";。这里有一个例子:

>>> df = pd.DataFrame({'a': ['1', '2', 'any', '3'], 'b': ['any', 'any', '3', '1']})
>>> df
a    b
0    1  any
1    2  any
2  any    3
3    3    1

就我而言;任何";意味着该值可以是"0";1〃"2〃;或";3〃;。我希望仅使用值"0"来生成所有可能的行;1〃"2〃;以及";3〃;(或者,一般来说,我可能拥有的任何价值观列表(。以下是上面例子的预期输出:

a  b
0  1  1
1  1  2
2  1  3
3  2  1
4  2  2
5  2  3
6  3  3
7  3  1

我用这种丑陋而复杂的方法得到了这个输出:

a = df['a'].replace('any', '1,2,3').apply(lambda x: eval(f'[{str(x)}]')).explode()
result = pd.merge(df.drop(columns=['a']), a, left_index=True, right_index=True)
b = result['b'].replace('any', '1,2,3').apply(lambda x: eval(f'[{str(x)}]')).explode()
result = pd.merge(result.drop(columns=['b']), b, left_index=True, right_index=True)
result = result.drop_duplicates().reset_index(drop=True)

有没有更简单和/或更好的方法?

您可以将字符串any替换为,例如'1,2,3',然后拆分和分解:

(df.replace('any', '1,2,3')
.apply(lambda x: x.str.split(',') if x.name in ['a','b'] else x)
.explode('a').explode('b')
.drop_duplicates(['a','b'])
)

输出:

a  b  c
0  1  1  1
0  1  2  1
0  1  3  1
1  2  1  1
1  2  2  1
1  2  3  1
2  3  3  1
3  3  1  1

我不会使用eval和字符串操作,而只是用一组值替换"any">

import pandas as pd
df = pd.DataFrame({'a': ['1', '2', 'any', '3'], 'b': ['any', 'any', '3', '1']})
df['c'] = '1'
df[df == 'any'] = {'1', '2', '3'}
for col in df:
df = df.explode(col)
df = df.drop_duplicates().reset_index(drop=True)
print(df)

这给出了的结果

a  b  c
0  1  2  1
1  1  3  1
2  1  1  1
3  2  2  1
4  2  3  1
5  2  1  1
6  3  3  1
7  3  1  1

最新更新