数据帧列值与lis的比较

2024-04-25 17:08:34 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑这个数据帧:

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)

现在我想添加一个新列,如果row的列C的值在firsts中,那么它将是“1”,否则它将是“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

如果有人能解释为什么我的解决方案是错误的,以及这个问题的实际解决方案是什么,我将不胜感激。


Tags: 数据lambdaindataframedfif解决方案else
3条回答

也可以使用.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

您可以使用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

您的方法失败的原因是pythonin运算符检查序列的索引而不是值,这与字典的工作方式相同:

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

TL;博士:

df['newColumn'] = np.where((df.compareColumn.isin(yourlist)), TrueValue, FalseValue)

另一个一步的方法是使用^{}^{}

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)

我们使用^{}中的返回作为^{}中的条件来返回

  • 1True
  • 0False

并将它们分配给同一数据帧中的新列df['D']

注意:np.where允许使用bitwise运算符和替换用例的更复杂条件,即False上的“旁路”

df['col1'] = np.where(((df['col1'] == df['col2']) &
                       (~df['col1'].str.startswith('r'))),
                       'replace', df['col1'])

相关问题 更多 >