考虑这个数据帧:
df = pd.DataFrame({'A': [1, 1, 2, 2, 3, 3],
'B': [10, 15, 20, 25, 30,35],
'C': [100, 150, 200, 250, 300, 350]},)
A B C
1 10 100
1 15 150
2 20 200
2 25 250
3 30 300
3 35 350
我用它来获取每组第一行的C列值:
firsts = df.groupby('A').first()['C']
首先是:(100, 200, 300)
。
现在我要添加新列,它将是' 1'如果行的列C的值在firsts
中,否则它将为' 0'。
A B C D
1 10 100 1
1 15 150 0
2 20 200 1
2 25 250 0
3 30 300 1
3 35 350 0
我用过这个:
df['D'] = df['C'].apply(lambda x: 1 if x in firsts else 0)
但输出是:
A B C D
1 10 100 0
1 15 150 0
2 20 200 0
2 25 250 0
3 30 300 0
3 35 350 0
我很感激,如果有人解释为什么我的解决方案是错误的,这个问题的实际解决方案是什么。
答案 0 :(得分:7)
您可以使用isin
方法:
df['D'] = df.C.isin(firsts).astype(int)
df
# A B C D
#0 1 10 100 1
#1 1 15 150 0
#2 2 20 200 1
#3 2 25 250 0
#4 3 30 300 1
#5 3 35 350 0
您的方法失败的原因是python in
运算符检查Series的索引而不是值,与字典的工作方式相同:
firsts
#A
#1 100
#2 200
#3 300
#Name: C, dtype: int64
1 in firsts
# True
100 in firsts
# False
2 in firsts
# True
200 in firsts
# False
按如下方式修改方法:
firstSet = set(firsts)
df['C'].apply(lambda x: 1 if x in firstSet else 0)
#0 1
#1 0
#2 1
#3 0
#4 1
#5 0
#Name: C, dtype: int64
答案 1 :(得分:1)
您也可以使用.transform('first')
:
In [280]: df['D'] = df.groupby('A')['C'].transform('first').eq(df['C']).astype(np.int8)
In [281]: df
Out[281]:
A B C D
0 1 10 100 1
1 1 15 150 0
2 2 20 200 1
3 2 25 250 0
4 3 30 300 1
5 3 35 350 0
说明: GroupBy.transform('func')
向我们返回一个与原始DF长度相同的向量,并应用了func
In [14]: df.groupby('A')['C'].transform('first')
Out[14]:
0 100
1 100
2 200
3 200
4 300
5 300
Name: C, dtype: int64
In [15]: df.groupby('A')['C'].transform('max')
Out[15]:
0 150
1 150
2 250
3 250
4 350
5 350
Name: C, dtype: int64
In [16]: df.groupby('A')['C'].transform('min')
Out[16]:
0 100
1 100
2 200
3 200
4 300
5 300
Name: C, dtype: int64
In [17]: df.groupby('A')['C'].transform('mean')
Out[17]:
0 125
1 125
2 225
3 225
4 325
5 325
Name: C, dtype: int64
In [18]: df.groupby('A')['C'].transform('sum')
Out[18]:
0 250
1 250
2 450
3 450
4 650
5 650
Name: C, dtype: int64
答案 2 :(得分:1)
<强> TL; DR:强>
df['newColumn'] = np.where((df.compareColumn.isin(yourlist)), TrueValue, FalseValue)
另一个单步方法是使用np.where()
和isin
。
import pandas as pd
import numpy as np
df = pd.DataFrame({'A': [1, 1, 2, 2, 3, 3],
'B': [10, 15, 20, 25, 30,35],
'C': [100, 150, 200, 250, 300, 350]})
df['D'] = np.where((df.B.isin(firsts)), 1, 0)
我们使用isin
的返回作为np.where()
中的条件返回
1
时,True
当0
False
并将它们分配到同一数据框df['D']
中的新列。
注意: np.where
允许使用bitwise运算符和替换案例的更复杂条件,即False
上的“绕过”
df['col1'] = np.where(((df['col1'] == df['col2']) &
(~df['col1'].str.startswith('r'))),
'replace', df['col1'])
答案 3 :(得分:-1)
firsts是pandas系列,因此当我们使用in搜索值时,它将在索引列表中搜索该值以解决此问题,我们可以将firsts转换为list或array
%timeit df['D'] = df['C'].apply(lambda x: 1 if x in firsts.values else 0)
每个循环314 µs±17.3 µs(平均±标准偏差,共运行7次,每个循环1000次)
或
%timeit df['D'] = df['C'].apply(lambda x: 1 if x in list(firsts) else 0)
每个循环301 µs±11.2 µs(平均±标准偏差,共运行7次,每个循环1000次)
或
%timeit df['D'] = list(map(lambda x: 1 if x in list(firsts) else 0,list(df['C'])))
每个循环27.6 µs±1.02 µs(平均±标准偏差,共运行7次,每个10000个循环)