Pandas DataFrame:根据条件替换列中的所有值

ich*_*mok 97 python dataframe pandas

我有一个简单的DataFrame,如下所示:

熊猫DataFrame

我想从"第一季"列中选择所有值,并将那些超过1990年的值替换为1.在此示例中,只有Baltimore Ravens将1996年替换为1(保持其余数据完好无损).

我使用了以下内容:

df.loc[(df['First Season'] > 1990)] = 1
Run Code Online (Sandbox Code Playgroud)

但是,它将该行中的所有值替换为1,而不仅仅是"第一季"列中的值.

如何只替换该列中的值?

EdC*_*ica 166

您需要选择该列:

In [41]:
df.loc[df['First Season'] > 1990, 'First Season'] = 1
df

Out[41]:
                 Team  First Season  Total Games
0      Dallas Cowboys          1960          894
1       Chicago Bears          1920         1357
2   Green Bay Packers          1921         1339
3      Miami Dolphins          1966          792
4    Baltimore Ravens             1          326
5  San Franciso 49ers          1950         1003
Run Code Online (Sandbox Code Playgroud)

所以这里的语法是:

df.loc[<mask>(here mask is generating the labels to index) , <optional column(s)> ]
Run Code Online (Sandbox Code Playgroud)

您可以查看文档以及显示语义的10分钟到熊猫

编辑

如果你想生成一个布尔值指标,那么你可以只使用布尔条件产生boolean值系列和铸铁的D型到int这将转换TrueFalse10分别为:

In [43]:
df['First Season'] = (df['First Season'] > 1990).astype(int)
df

Out[43]:
                 Team  First Season  Total Games
0      Dallas Cowboys             0          894
1       Chicago Bears             0         1357
2   Green Bay Packers             0         1339
3      Miami Dolphins             0          792
4    Baltimore Ravens             1          326
5  San Franciso 49ers             0         1003
Run Code Online (Sandbox Code Playgroud)


Ami*_*r F 24

派对有点晚了但仍然 - 我更喜欢使用numpy:

import numpy as np
df['First Season'] = np.where(df['First Season'] > 1990, 1, df['First Season'])
Run Code Online (Sandbox Code Playgroud)

  • pandas 现在有一个内置的 `where` 方法,与 https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.where 中的 `np.where` 进行比较.html#pandas.DataFrame.where (3认同)
  • 我正在寻找一种有条件地覆盖列值的解决方案,但基于其他列的值,如下所示: df['col1'] = np.where(df['id'] == '318431682259014', 'NEW', df['col1']) 这就是它的解决方案。 (2认同)
  • 我试图在这样的多个条件下执行此操作,但我不断收到“ValueError:系列的真值不明确”。使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()`。我想做的基本上是 `df['A'] = np.where(df['B'] in some_values, df['A']*2, df['A]`。有人有吗对此有何想法? (2认同)

小智 20

df.loc[df['First season'] > 1990, 'First Season'] = 1
Run Code Online (Sandbox Code Playgroud)

解释:

df.loc有两个参数:“行索引”和“列索引”。我们正在检查“第一季”列下每行值的值是否大于 1990,然后将其替换为 1。


Odz*_*Odz 11

df['First Season'].loc[(df['First Season'] > 1990)] = 1
Run Code Online (Sandbox Code Playgroud)

奇怪的是没有人有这个答案,你的代码唯一缺少的部分是 df 之后的 ['First Season'] ,只需删除里面的大括号。

  • 这给出了“SettingWithCopyWarning:”最好使用 .loc 来完成整个事情,就像 EdChum 的答案一样。 (3认同)

tdy*_*tdy 8

TLDR \xe2\x80\x94 这里是一些使用指南,包括一些还没有提到的方法:

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n
使用案例受到推崇的例子
速度DataFrame.locdf.loc[df[\'A\'] < 10, \'A\'] = 1
方法链接Series.maskdf[\'A\'] = df[\'A\'].mask(df[\'A\'] < 10, 1).method1().method2()
整个数据框DataFrame.maskdf = df.mask(df[\'A\'] < 10, df**2)
多种条件np.selectdf[\'A\'] = np.select([df[\'A\'] < 10, df[\'A\'] > 20], [1, 2], default=df[\'A\'])
\n

1. 速度

\n

DataFrame.loc如果您有一个大数据框并且关心速度,请使用:

\n
df.loc[df[\'Season\'] > 1990, \'Season\'] = 1\n
Run Code Online (Sandbox Code Playgroud)\n

对于小型数据帧,速度微不足道,但从技术上讲,如果您愿意,还有更快的选择:

\n

\n

df = pd.DataFrame({\'Team\': np.random.choice([*\'ABCDEFG\'], size=n), \'Season\': np.random.randint(1900, 2001, size=n), \'Games\': np.random.randint(0, 17, size=n)})

\n

2. 方法链

\n

Series如果您想有条件地替换方法链中的值,请使用方法:

\n\n

链接的好处在 OP 的示例中并不明显,但在其他情况下非常有用。就像一个玩具示例:

\n
# compute average games per team, but pre-1972 games are weighted by half\ndf[\'Games\'].mask(df[\'Season\'] < 1972, 0.5*df[\'Games\']).groupby(df[\'Team\']).mean()\n
Run Code Online (Sandbox Code Playgroud)\n

实际例子:

\n\n

3. 整个数据框

\n

DataFrame.mask如果您想有条件地替换整个数据帧中的值,请使用。

\n

根据 OP 的示例,想出一个有意义的示例并不容易,但这里有一个简单的演示示例:

\n
# replace the given elements with the doubled value (or repeated string)\ndf.mask(df.isin([\'Chicago Bears\', \'Buffalo Bills\', 8, 1990]), 2*df)\n
Run Code Online (Sandbox Code Playgroud)\n

实际例子:

\n\n

4. 多种条件

\n

np.select如果您有多个条件,每个条件都有不同的替换,请使用:

\n
# replace pre-1920 seasons with 0 and post-1990 seasons with 1\nconditions = {\n    0: df[\'Season\'] < 1920,\n    1: df[\'Season\'] > 1990,\n}\ndf[\'Season\'] = np.select(conditions.values(), conditions.keys(), default=df[\'Season\'])\n
Run Code Online (Sandbox Code Playgroud)\n

实际例子:

\n\n


Har*_*ain 6

对于单一条件,即( 'employrate'] > 70 )

       country        employrate alcconsumption
0  Afghanistan  55.7000007629394            .03
1      Albania  51.4000015258789           7.29
2      Algeria              50.5            .69
3      Andorra                            10.17
4       Angola  75.6999969482422           5.57
Run Code Online (Sandbox Code Playgroud)

用这个:

df.loc[df['employrate'] > 70, 'employrate'] = 7
Run Code Online (Sandbox Code Playgroud)
       country  employrate alcconsumption
0  Afghanistan   55.700001            .03
1      Albania   51.400002           7.29
2      Algeria   50.500000            .69
3      Andorra         nan          10.17
4       Angola    7.000000           5.57
Run Code Online (Sandbox Code Playgroud)

因此这里的语法是:

df.loc[<mask>(here mask is generating the labels to index) , <optional column(s)> ]
Run Code Online (Sandbox Code Playgroud)

对于多个条件,即。(df['employrate'] <=55) & (df['employrate'] > 50)

用这个:

df['employrate'] = np.where(
   (df['employrate'] <=55) & (df['employrate'] > 50) , 11, df['employrate']
   )
Run Code Online (Sandbox Code Playgroud)
out[108]:
       country  employrate alcconsumption
0  Afghanistan   55.700001            .03
1      Albania   11.000000           7.29
2      Algeria   11.000000            .69
3      Andorra         nan          10.17
4       Angola   75.699997           5.57
Run Code Online (Sandbox Code Playgroud)

因此这里的语法是:

 df['<column_name>'] = np.where((<filter 1> ) & (<filter 2>) , <new value>, df['column_name'])
Run Code Online (Sandbox Code Playgroud)