[英]Generate an edge list from a pandas dataframe
假设我有一个这样的熊猫数据框:
Fruit_1 Fruit_2 Fruit_3
0 Apple Orange Peach
1 Apple Lemon Lime
2 Starfruit Apple Orange
可复制形式:
df = pd.DataFrame([['Apple', 'Orange', 'Peach'],
['Apple', 'Lemon', 'Lime'],
['Starfruit', 'Apple', 'Orange']],
columns=['Fruit_1', 'Fruit_2', 'Fruit_3'])
我想生成一个边缘列表,其中包括:
Apple, Orange
Apple, Peach
Orange, Peach
Apple, Lemon
Apple, Lime
Lemon, Lime
Starfruit, Apple
Starfruit, Orange
Apple, Orange
我如何在 Python 中做到这一点?
我不知道熊猫,但你可以在行上使用itertools.combinations
itertools.combinations(row, 2)
这将创建一个迭代器,您可以简单地将其转换为对列表。
在将这些列表收集到列表后加入这些列表可以使用平面列表理解来完成
[pair for row in collected_rows for pair in row]
或者使用通常更快的numpy
方式
data[:, np.c_[np.tril_indices(data.shape[1], -1)]]
如果你想要一个平面列表
data[:, np.c_[np.triu_indices(data.shape[1], 1)]].reshape(-1,2)
请注意, triu_indices
按顺序列出顶点,而tril_indices
以相反的方式列出它们。 它们通常用于获取矩阵的上三角形或下三角形的索引。
这是一个熊猫解决方案:
In [118]: from itertools import combinations
In [119]: df.apply(lambda x: list(combinations(x, 2)), 1).stack().reset_index(level=[0,1], drop=True).apply(', '.join)
Out[119]:
0 Apple, Orange
1 Apple, Peach
2 Orange, Peach
3 Apple, Lemon
4 Apple, Lime
5 Lemon, Lime
6 Starfruit, Apple
7 Starfruit, Orange
8 Apple, Orange
dtype: object
我写这篇文章可能有点晚了,但最近我有必要完全按照你的要求去做。 我设法避免在这种情况下使用 itertools。 如果这是您的数据框:
df = pd.DataFrame([['Apple', 'Orange', 'Peach'],
['Apple', 'Lemon', 'Lime'],
['Starfruit', 'Apple', 'Orange']],
columns=['Fruit_1', 'Fruit_2', 'Fruit_3'])
您只需调用一个函数:
>>> edgelist = get_edgelist(df)
ID1 ID2
0 Apple Orange
1 Apple Peach
2 Orange Peach
3 Apple Lemon
4 Apple Lime
5 Lemon Lime
6 Apple Orange
7 Apple Starfruit
8 Orange Starfruit
定义为:
def fast_combinations(row : list, self_loops = False) -> np.array:
try:
if self_loops:
comb = np.unique(np.sort(np.array(np.meshgrid(row, row)).T.reshape(-1,2)), axis=0)
else:
comb = np.unique(np.sort(np.array(np.meshgrid(row, row)).T.reshape(-1,2)), axis=0)
comb = np.delete(comb, np.where(comb[:,0] == comb[:,1]), axis=0)
return comb
except:
return [[None, None]]
def get_edgelist(df, **kwargs):
cols = df.columns
df['combined'] = df[df.columns].values.tolist()
# Clear space
df.drop(cols, axis=1, inplace=True)
arrays = []
for row in range(len(df.index)):
arrays.append(fast_combinations(df.loc[row, 'combined'], kwargs))
return pd.DataFrame(np.concatenate( arrays, axis=0 ), columns=['ID1', 'ID2']).replace('nan', None).dropna().reset_index(drop=True)
我从函数中删除了描述以使其更易于阅读,但您可以在此处找到它们https://gist.github.com/Stefano314/607db3ffc53d680d60de61d09ca39a08 。
我在一个 250 万行的数据帧上使用了它,从中我得到了 4500 万个关联,我在 i7-3770 上花了大约 48 分钟。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.