我有一个包含 A 、B 、C 列的数据框。我想比较 B 和 C 列并创建两列,即 A-1(当前行年份 -1)和 A-2(当前行年份 -2)其中 A 是年份列。
示例:在 1971 年的数据框中,B 列有 apple 、 Orange C 列只有苹果,1970 年有 B-香蕉、苹果和 C-苹果。 现在,对于 1971 年的每一行,我们尝试生成 A-1(1970) 和 A-2(1969) 列的值。在 (A-1)1970 年,苹果在 B、C 列中都被捕获,因此我们将 1971 年的前两行标记为"is",然后将第三行标记为“否”,因为 1970 年没有橙色。
因此,对于每一行,我们考虑年份(例如 1971 年)并检查 B 和 C 值,并查看该特定 B 值是否也在 Year-1(1970)和 Year-2(1969)的 C 列中捕获,在这种情况下,它将是 nan,因为我们的数据框中没有任何 1969 的记录)并相应地标记它们。
数据框:
A B C D
1971 apple apple yes
1971 apple apple yes
1971 orange nan no
1970 banana nan no
1970 apple apple yes
1972 mango mango yes
1972 banana banana yes
1972 orange orange yes
1972 apple apple yes
1973 banana nan no
1973 mango mango yes
1973 apple nan no
1974 orange nan no
输出:
A B C A-1 A-2
1971 apple apple yes nan
1971 apple apple yes nan
1971 orange nan no nan
1970 banana nan nan nan
1970 apple apple nan nan
1972 mango mango no no
1972 banana banana no no
1972 orange orange no no
1972 apple apple yes yes
1973 banana nan yes no
1973 mango mango yes no
1973 apple nan yes yes
1974 orange nan no yes
我不明白,请帮我解决这个问题。
最佳答案
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
来识别应标记为"is"的行与它自己,
匹配列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()
的目的多于。如果没有它,我们在合并时就会丢失原始索引。
关于python - pandas 匹配两列并创建另一列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54159234/