Есть ли эффективный способ выбрать несколько строк в большом кадре данных панд? - PullRequest
1 голос
/ 31 марта 2019

Я работаю над адатомами с большими пандами, около 100 миллионов строк и 2 столбца. Я хочу перебрать данные и эффективно установить третий столбец в зависимости от значений 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).

Ответы [ 3 ]

1 голос
/ 31 марта 2019

Мое решение состояло бы в том, чтобы объединить кадр с самим собой (объединить столбец 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 голос
/ 31 марта 2019

В тех же строках, что и в ответе @ 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
0 голосов
/ 31 марта 2019

Использование:

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]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...