我有一个列表数据集列表:
data_set = [['note_a', 'mix'],['note_b', 'mix'], ['mix','leave','note_a','note_b','random'],['mix','random','note_a','note_b']]
我正在使用它的笛卡尔积:
import itertools
all_method = pd.DataFrame(itertools.product(*data_set))
all_method
输出
0 1 2 3
0 note_a note_b mix mix
1 note_a note_b mix random
2 note_a note_b mix note_a
3 note_a note_b mix note_b
4 note_a note_b leave mix
.. ... ... ... ...
75 mix mix note_b note_b
76 mix mix random mix
77 mix mix random random
78 mix mix random note_a
79 mix mix random note_b
[80 rows x 4 columns]
现在我想用三个新值扩展每个混合值:
mix = ['copy_a', 'copy_b', 'copy_c']
因此,如果连续存在混合,则应扩展三行,并用每个值替换混合。
我要看的三行示例:
[('note_a', 'note_b', 'copy_a', 'copy_a'), ('note_a', 'note_b', 'copy_b', 'copy_b'), ('note_a', 'note_b', 'copy_c','copy_c'),
('note_a', 'note_b', 'copy_a', 'random'), ('note_a', 'note_b', 'copy_b', 'random'), ('note_a', 'note_b', 'copy_c', 'random'),
('note_a', 'note_b', 'copy_a', 'note_a'), ('note_a', 'note_b', 'copy_b', 'note_a'), ('note_a', 'note_b', 'copy_c', 'note_a')]
在第一行中,有两个“ mix”,因此它扩展了三行,其中“ copy_a”填充为“ mix”,然后是“ copy_b”填充为“ mix”,最后是“ copy_c”填充为“ mix”。
我尝试过的:
import itertools
all_method = list(itertools.product(*data_set))
all_method
def extend_rows_func(data):
extend_rows = []
mix = ['copy_a', 'copy_b', 'copy_c']
for i in data:
if 'mix' in i:
for copy_op in mix:
extend_rows.append([copy_op if x== 'mix' else x for x in i])
else:
extend_rows.append(list(i))
return extend_rows
是否有任何优化的方法或熊猫方法而不使用三个循环?
答案 0 :(得分:1)
您可以先考虑replace
然后考虑concat
:
pd.concat(all_method.replace('mix',copy) for copy in ['copy_a', 'copy_b', 'copy_c'])
输出:
0 1 2 3
0 note_a note_b copy_a copy_a
1 note_a note_b copy_a random
2 note_a note_b copy_a note_a
3 note_a note_b copy_a note_b
4 note_a note_b leave copy_a
.. ... ... ... ...
75 copy_c copy_c note_b note_b
76 copy_c copy_c random copy_c
77 copy_c copy_c random random
78 copy_c copy_c random note_a
79 copy_c copy_c random note_b
[240 rows x 4 columns]
如果要将原始行排列在一起,可以将其与sort_index()
链接起来:
(pd.concat(all_method.replace('mix',copy)
for copy in ['copy_a', 'copy_b', 'copy_c'])
.sort_index()
)
输出:
0 1 2 3
0 note_a note_b copy_a copy_a
0 note_a note_b copy_b copy_b
0 note_a note_b copy_c copy_c
1 note_a note_b copy_a random
1 note_a note_b copy_b random
.. ... ... ... ...
78 copy_a copy_a random note_a
78 copy_b copy_b random note_a
79 copy_b copy_b random note_b
79 copy_a copy_a random note_b
79 copy_c copy_c random note_b
[240 rows x 4 columns]
答案 1 :(得分:0)
请注意,此方法需要一些时间才能运行
mid=all_method.replace('mix',','.join(['copy_a', 'copy_b', 'copy_c'])).applymap(lambda x: x.split(','))
def unnesting_cell(df):
explode = df.columns[df.iloc[0].str.len()>1]
if len(explode) == 0 :
return df
else:
df1 = pd.concat([
pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
df1.index=df.index.tolist()*len(df1)
return df1.join(df.drop(explode, 1).apply(lambda x : x.str[0] , axis=1), how='left')
df = pd.concat([unnesting_cell(mid.loc[[x]]) for x in mid.index])