私はあなたが計算することをお勧めしますadditions
し、removals
同じ内適用されます。
より大きな例を生成する
import pandas as pd
import numpy as np
df = pd.DataFrame({'today': [['a', 'b', 'c'], ['a', 'b'], ['b']],
'yesterday': [['a', 'b'], ['a'], ['a']]})
df = pd.concat([df for i in range(10_000)], ignore_index=True)
あなたの解決策
%%time
additions = df.apply(lambda row: np.setdiff1d(row.today, row.yesterday), axis=1)
removals = df.apply(lambda row: np.setdiff1d(row.yesterday, row.today), axis=1)
CPU times: user 10.9 s, sys: 29.8 ms, total: 11 s
Wall time: 11 s
1回の適用でのソリューション
%%time
df["out"] = df.apply(lambda row: [np.setdiff1d(row.today, row.yesterday),
np.setdiff1d(row.yesterday, row.today)], axis=1)
df[['additions','removals']] = pd.DataFrame(df['out'].values.tolist(), columns=['additions','removals'])
df = df.drop("out", axis=1)
CPU times: user 4.97 s, sys: 16 ms, total: 4.99 s
Wall time: 4.99 s
使用する set
あなたのリストが非常に大きくない限り、あなたは避けることができます numpy
def fun(x):
a = list(set(x["today"]).difference(set(x["yesterday"])))
b = list((set(x["yesterday"])).difference(set(x["today"])))
return [a,b]
%%time
df["out"] = df.apply(fun, axis=1)
df[['additions','removals']] = pd.DataFrame(df['out'].values.tolist(), columns=['additions','removals'])
df = df.drop("out", axis=1)
CPU times: user 1.56 s, sys: 0 ns, total: 1.56 s
Wall time: 1.56 s
@ r.ookのソリューション
リストの代わりにセットを出力として使用することに満足している場合は、@ r.ookのコードを使用できます。
%%time
temp = df[['today', 'yesterday']].applymap(set)
removals = temp.diff(periods=1, axis=1).dropna(axis=1)
additions = temp.diff(periods=-1, axis=1).dropna(axis=1)
CPU times: user 93.1 ms, sys: 12 ms, total: 105 ms
Wall time: 104 ms
@Andreas K.のソリューション
%%time
df['additions'] = (df['today'].apply(set) - df['yesterday'].apply(set))
df['removals'] = (df['yesterday'].apply(set) - df['today'].apply(set))
CPU times: user 161 ms, sys: 28.1 ms, total: 189 ms
Wall time: 187 ms
最終的に追加.apply(list)
して同じ出力を取得できます