假设我有一个熊猫数据帧,如下所示:
my_id val_a_b val_a val_c
0 id_1 rat|white rat 1
1 id_2 dog|brown dog 0
和这样的列表:
val_a_list = ['rat', 'dog', 'cow']
我想多次复制每一行,并根据val_a_list
中的每个值替换val_a_b
和val_a
列中的值(除非val_a
中的值与val_a_list
中的元素相同(,保持所有其他列的值相同。
所需数据帧:
my_id val_a_b val_a val_c
0 id_1 rat|white rat 1
1 id_2 dog|brown dog 0
2 id_1 dog|white dog 1
3 id_1 cow|white cow 1
4 id_2 rat|brown rat 0
5 id_2 cow|brown cow 0
注:第2行和第3行基于第0行,第4行和第5行基于第1行。
这是我的代码,它对每一行进行迭代。我正在寻找更好的解决方案:
def replicate_val_a_in_df(df, val_a_list):
df_base_size = df.shape[0]
for i in range(df_base_size):
for new_val_a in val_a_list:
val_a_b = df.iloc[i]['val_a_b']
val_a_b_parts = val_a_b.split('|')
original_val_a = val_a_b_parts[0]
if new_val_a != original_val_a:
val_b = val_a_b_parts[1]
new_val_a_b = "|".join([new_val_a, val_b])
df.append(df.iloc[i], ignore_index=True)
df.iloc[-1, df.columns.get_loc('val_a')] = new_val_a
df.iloc[-1, df.columns.get_loc('val_a_b')] = new_val_a_b
return df
我看过这个答案,但它在所有重复的行中设置了相同的列值
IIUC您可以创建一个dict
,这样您就可以创建map
和explode
,并最终重建列b:
d = {i: val_a_list for i in val_a_list}
df = df.assign(val_a=df["val_a"].map(d).fillna(df["val_a"])).explode("val_a")
df["val_a_b"] = df["val_a"]+"|"+df["val_a_b"].str.split("|").str[-1]
print (df)
my_id val_a_b val_a val_c
0 id_1 rat|white rat 1
0 id_1 dog|white dog 1
0 id_1 cow|white cow 1
1 id_2 rat|brown rat 0
1 id_2 dog|brown dog 0
1 id_2 cow|brown cow 0