import numpy as np
import pandas as pd
nan = np.nan
df = pd.DataFrame({'A': [1971, 1971, 1971, 1970, 1970, 1972, 1972, 1972, 1972, 1973, 1973, 1973, 1974], 'B': ['apple', 'apple', 'orange', 'banana', 'apple', 'mango', 'banana', 'orange', 'apple', 'banana', 'mango', 'apple', 'orange'], 'C': ['apple', 'apple', nan, nan, 'apple', 'mango', 'banana', 'orange', 'apple', nan, 'mango', nan, nan]})
# add an index column to the DataFrame
df = df.reset_index()
df['BC'] = np.where(df['B'] == df['C'], df['B'], nan)
A_min = df['A'].min()
for i in [1, 2]:
col = 'A-{}'.format(i)
col2 = 'Y+{}'.format(i)
df[col2] = df['A']+i
# fill with nans
df[col] = nan
# place 'no' except where there is no data for the year A-i
mask = df['A']-i >= A_min
df.loc[mask, col] = 'no'
# place 'yes' where 'A','B' columns match 'Y+i','BC' columns
match = pd.merge(df[['A','B','index']], df[[col2, 'BC']],
left_on=['A','B'], right_on=[col2,'BC'])
df.loc[match['index'], col] = 'yes'
df = df.drop(['index', 'BC', 'Y+1', 'Y+2'], axis=1)
print(df)
выходы
A B C A-1 A-2
0 1971 apple apple yes NaN
1 1971 apple apple yes NaN
2 1971 orange NaN no NaN
3 1970 banana NaN NaN NaN
4 1970 apple apple NaN NaN
5 1972 mango mango no no
6 1972 banana banana no no
7 1972 orange orange no no
8 1972 apple apple yes yes
9 1973 banana NaN yes no
10 1973 mango mango yes no
11 1973 apple NaN yes yes
12 1974 orange NaN no yes
Как это работает:
Сначала добавим столбец индекса в DataFrame. Его цель станет понятнее позже. (Обратите внимание, что я предполагаю, что исходный индекс вашего DataFrame имеет уникальную ценность. Мы будем полагаться на это свойство позже ...)
df = df.reset_index()
# index A B C
# 0 0 1971 apple apple
# 1 1 1971 apple apple
# 2 2 1971 orange NaN
# 3 3 1970 banana NaN
# 4 4 1970 apple apple
# 5 5 1972 mango mango
# 6 6 1972 banana banana
# 7 7 1972 orange orange
# 8 8 1972 apple apple
# 9 9 1973 banana NaN
# 10 10 1973 mango mango
# 11 11 1973 apple NaN
# 12 12 1974 orange NaN
Поскольку мы хотим идентифицировать строки с определенным значением , которое одинаково в столбцах B
и C
, давайте создадим столбец BC
, равный B
, когда B
и C
равны, а NaN
, когда они не равны:
In [123]: df['BC'] = np.where(df['B'] == df['C'], df['B'], nan)
In [124]: df
Out[124]:
index A B C BC
0 0 1971 apple apple apple
1 1 1971 apple apple apple
2 2 1971 orange NaN NaN
3 3 1970 banana NaN NaN
4 4 1970 apple apple apple
5 5 1972 mango mango mango
6 6 1972 banana banana banana
7 7 1972 orange orange orange
8 8 1972 apple apple apple
9 9 1973 banana NaN NaN
10 10 1973 mango mango mango
11 11 1973 apple NaN NaN
12 12 1974 orange NaN NaN
Теперь мы собираемся сопоставлять строки разных лет, поэтому давайте добавим столбец, чтобы определить, какие годы нам интересно сравнивать. Например, мы хотим сравнить строки, когда A
равен 1971, со строками, когда Y+1
равно 1971:
In [125]: df['Y+1'] = df['A']+1; df
Out[125]:
index A B C BC Y+1
0 0 1971 apple apple apple 1972
1 1 1971 apple apple apple 1972
2 2 1971 orange NaN NaN 1972
3 3 1970 banana NaN NaN 1971
4 4 1970 apple apple apple 1971
5 5 1972 mango mango mango 1973
6 6 1972 banana banana banana 1973
7 7 1972 orange orange orange 1973
8 8 1972 apple apple apple 1973
9 9 1973 banana NaN NaN 1974
10 10 1973 mango mango mango 1974
11 11 1973 apple NaN NaN 1974
12 12 1974 orange NaN NaN 1975
С помощью этой настройки мы можем идентифицировать строки, которые должны быть помечены как «да», объединяя df
с собой,
соответствующие столбцы A
и B
с столбцами Y+1
и BC
:
In [127]: pd.merge(df[['A','B','index']], df[['Y+1', 'BC']], left_on=['A','B'], right_on=['Y+1','BC'])
Out[127]:
A B index Y+1 BC
0 1971 apple 0 1971 apple
1 1971 apple 1 1971 apple
2 1972 apple 8 1972 apple
3 1972 apple 8 1972 apple
4 1973 banana 9 1973 banana
5 1973 mango 10 1973 mango
6 1973 apple 11 1973 apple
Обратите внимание, что в столбце index
указаны индексы строк, которые должны содержать yes
в столбце A-1
. Это цель для использования df = df.reset_index()
выше. Без него мы потеряли бы исходный индекс при слиянии.