2 回答

TA貢獻1876條經(jīng)驗 獲得超6個贊
為什么不為此做一個簡單的合并?
df = pd.DataFrame({'from_id': ['X', 'Z', 'Y'], 'to_id': ['Y', 'Y', 'X'], 'count': [3,4,2]})
pd.merge(
? left = df,?
? right = df,?
? how = 'left',?
? left_on = ['from_id', 'to_id'],?
? right_on = ['to_id', 'from_id']
)
? from_id_x to_id_x? count_x from_id_y to_id_y? count_y
0? ? ? ? ?X? ? ? ?Y? ? ? ? 3? ? ? ? ?Y? ? ? ?X? ? ? 2.0
1? ? ? ? ?Z? ? ? ?Y? ? ? ? 4? ? ? ?NaN? ? ?NaN? ? ? NaN
2? ? ? ? ?Y? ? ? ?X? ? ? ? 2? ? ? ? ?X? ? ? ?Y? ? ? 3.0
這里我們合并 from (from, to) -> (to, from) 得到反向匹配對。一般來說,你應(yīng)該避免使用,apply()
因為它很慢。(要理解為什么,意識到它不是矢量化操作。)

TA貢獻1840條經(jīng)驗 獲得超5個贊
您可以使用.set_indextwice 創(chuàng)建兩個具有相反索引順序的數(shù)據(jù)幀,并分配以創(chuàng)建您的 inverse_count 列。
df = (df.set_index(['from_id','to_id'])
? ? ? ? .assign(inverse_count=df.set_index(['to_id','from_id'])['count'])
? ? ? ? .reset_index())
? from_id to_id? count? inverse_count
0? ? ? ?X? ? ?Y? ? ? 3? ? ? ? ? ? 2.0
1? ? ? ?Z? ? ?Y? ? ? 4? ? ? ? ? ? NaN
2? ? ? ?Y? ? ?X? ? ? 2? ? ? ? ? ? 3.0
由于問題是關(guān)于速度的,讓我們看看在更大數(shù)據(jù)集上的性能:
設(shè)置:
import pandas as pd
import string
import itertools
df = pd.DataFrame(list(itertools.permutations(string.ascii_uppercase, 2)), columns=['from_id', 'to_id'])
df['count'] = df.index % 25 + 1
print(df)
? ? from_id to_id? count
0? ? ? ? ?A? ? ?B? ? ? 1
1? ? ? ? ?A? ? ?C? ? ? 2
2? ? ? ? ?A? ? ?D? ? ? 3
3? ? ? ? ?A? ? ?E? ? ? 4
4? ? ? ? ?A? ? ?F? ? ? 5
..? ? ? ...? ?...? ? ...
645? ? ? ?Z? ? ?U? ? ?21
646? ? ? ?Z? ? ?V? ? ?22
647? ? ? ?Z? ? ?W? ? ?23
648? ? ? ?Z? ? ?X? ? ?24
649? ? ? ?Z? ? ?Y? ? ?25
設(shè)置索引:
%timeit (df.set_index(['from_id','to_id'])
? ? ? ? ? ?.assign(inverse_count=df.set_index(['to_id','from_id'])['count'])
? ? ? ? ? ?.reset_index())
6 ms ± 24.7 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
合并:
%timeit pd.merge(
? ? ? ? ? left = df,
? ? ? ? ? right = df,
? ? ? ? ? how = 'left',
? ? ? ? ? left_on = ['from_id', 'to_id'],
? ? ? ? ? right_on = ['to_id', 'from_id'] )
1.73 ms ± 57.5 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
因此,看起來合并方法是更快的選擇。
添加回答
舉報