我正在研究一个约有1亿行和2列的大熊猫adatframe。我想遍历数据框并根据col1和col2的值有效地设置第三列。这就是我目前正在做的-
df[col3] = 0
for idx, row in df.iterrows():
val1 = row[col1]
val2 = row[col2]
df1 = df.loc[(df.col1 == val2) & (df.col2 == val1)]
if len(df1) > 0:
df.loc[(df.col1 == val2) & (df.col2 == val1), col3] = 1
Example:
df = pd.DataFrame({'col1':[0,1,2,3,4,11], 'col2':[10,11,12,4,3,0]})
>> df.head()
col1 col2
0 0 10
1 1 11
2 2 12
3 3 4
4 4 3
5 3 10
I want to add 'col3' such that last 2 rows of the third column are
1. Think of it as a reverse_edge column which is 1 when for each
(val1, val2) in col1, col2 there is a (val2, val1) in col1, col2
col1 col2 col3
0 0 10 0
1 1 11 0
2 2 12 0
3 3 4 1
4 4 3 1
5 11 0 0
进行此计算的最有效方法是什么?目前,遍历整个数据框需要花费我几个小时。
编辑:将col1中的每个值和col2中的对应值视为图形中的一条边(val1-> val2)。我想知道是否存在反向边缘(val2-> val1)。
答案 0 :(得分:1)
我的解决方案是将框架合并到自身(将第2列合并到第1列),然后检查其他两列是否相同:这意味着相反的情况也存在:
df2 = df.merge(df, how='left', left_on='col2', right_on='col1')
df['rev_exists'] = (df2['col1_x'] == df2['col2_y']).astype(int)
df
# col1 col2 rev_exists
#0 0 10 0
#1 1 11 0
#2 2 12 0
#3 3 4 1
#4 4 3 1
#5 11 0 0
答案 1 :(得分:1)
与@Jondiedoop的回答相同,您可以安全地进行一些后缀争用并通过一次合并两个列来保持内部联接,
df['col3'] = df.index.isin(df.merge(df, left_on=['col1', 'col2'], right_on=['col2', 'col1'], left_index=True).index).astype(int)
例如:
In [40]: df
Out[40]:
col1 col2
0 0 10
1 1 11
2 2 12
3 3 4
4 4 3
5 11 0
6 0 10
In [41]: df['col3'] = df.index.isin(df.merge(df, left_on=['col1', 'col2'], right_on=['col2', 'col1'], left_index=True).index).astype(int)
In [42]: df
Out[42]:
col1 col2 col3
0 0 10 0
1 1 11 0
2 2 12 0
3 3 4 1
4 4 3 1
5 11 0 0
6 0 10 0
等效的方法是:
df['col3'] = 0
df.loc[df.merge(df, left_on=['col1', 'col2'], right_on=['col2', 'col1'], left_index=True).index, 'col3'] = 1
答案 2 :(得分:0)
使用:
df1 = pd.DataFrame(np.sort(df[['col1', 'col2']], axis=1), index=df.index)
df['col3'] = df1.duplicated(keep=False).astype(int)
print (df)
col1 col2 col3
0 0 10 0
1 1 11 0
2 2 12 0
3 3 4 1
4 4 3 1
另一种具有merge
的解决方案,比较子集,与2d array
比较,最后使用np.all
来检查每行中的所有True
:
df2 = df.merge(df, how='left', left_on='col2', right_on='col1')
df['col3'] = ((df2[['col1_x','col2_x']].values ==
df2[['col2_y','col1_y']].values).all(axis=1).astype(int))
#pandas 0.24+
#https://stackoverflow.com/a/54508052
#df['col3'] = ((df2[['col1_x','col2_x']].to_numpy() ==
df2[['col2_y','col1_y']].to_numpy()).all(axis=1).astype(int))
print (df)
col1 col2 col3
0 0 10 0
1 1 11 0
2 2 12 0
3 3 4 1
4 4 3 1
5 11 0 0
print ((df2[['col1_x','col2_x']].values == df2[['col2_y','col1_y']].values))
[[False False]
[False True]
[False False]
[ True True]
[ True True]
[False True]]