根据另一列中的值设置一个熊猫列的值

我需要根据熊猫数据框中另一列的值来设置一列的值。这就是逻辑:

if df['c1'] == 'Value':
df['c2'] = 10
else:
df['c2'] = df['c3']

I am unable to get this to do what I want, which is to simply create a column with new values (or change the value of an existing column: either one works for me).

如果我尝试运行上面的代码,或者将其作为函数编写并使用 application 方法,我会得到以下结果:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

366699 次浏览

尝试:

df['c2'] = df['c1'].apply(lambda x: 10 if x == 'Value' else x)

一种方法是使用 .loc的索引。

例子

In the absence of an example dataframe, I'll make one up here:

import numpy as np
import pandas as pd


df = pd.DataFrame({'c1': list('abcdefg')})
df.loc[5, 'c1'] = 'Value'


>>> df
c1
0      a
1      b
2      c
3      d
4      e
5  Value
6      g

假设您想要 创建一个新列 c2,相当于 c1,除了 c1Value,在这种情况下,您希望将它赋值为10:

First, you could create a new column c2, and set it to equivalent as c1, using one of the following two lines (they essentially do the same thing):

df = df.assign(c2 = df['c1'])
# OR:
df['c2'] = df['c1']

然后,使用 .loc找出所有 c1等于 'Value'的索引,并按照这些索引在 c2中分配你想要的值:

df.loc[df['c1'] == 'Value', 'c2'] = 10

然后你得到了这个:

>>> df
c1  c2
0      a   a
1      b   b
2      c   c
3      d   d
4      e   e
5  Value  10
6      g   g

如果正如您在问题中建议的那样,您可能有时只想创建 替换已有的列中的值,而不是创建一个新列,那么只需跳过创建列,执行以下操作:

df['c1'].loc[df['c1'] == 'Value'] = 10
# or:
df.loc[df['c1'] == 'Value', 'c1'] = 10

给你:

>>> df
c1
0      a
1      b
2      c
3      d
4      e
5     10
6      g

可以使用 np.where()根据指定的条件设置值:

#df
c1  c2  c3
0   4   2   1
1   8   7   9
2   1   5   8
3   3   3   5
4   3   6   8

现在根据您的条件更改 ['c2']列中的值(或设置)。

df['c2'] = np.where(df.c1 == 8,'X', df.c3)


c1  c2  c3
0   4   1   1
1   8   X   9
2   1   8   8
3   3   5   5
4   3   8   8

I suggest doing it in two steps:

# set fixed value to 'c2' where the condition is met
df.loc[df['c1'] == 'Value', 'c2'] = 10


# copy value from 'c3' to 'c2' where the condition is NOT met
df.loc[df['c1'] != 'Value', 'c2'] = df[df['c1'] != 'Value', 'c3']

您可以使用 pandas.DataFrame.mask添加几乎所有您需要的条件:

data = {'a': [1,2,3,4,5], 'b': [6,8,9,10,11]}


d = pd.DataFrame.from_dict(data, orient='columns')
c = {'c1': (2, 'Value1'), 'c2': (3, 'Value2'), 'c3': (5, d['b'])}


d['new'] = np.nan
for value in c.values():
d['new'].mask(d['a'] == value[0], value[1], inplace=True)


d['new'] = d['new'].fillna('Else')
d

Output:

    a   b   new
0   1   6   Else
1   2   8   Value1
2   3   9   Value2
3   4   10  Else
4   5   11  11

Try out df.apply() if you've a small/medium dataframe,

df['c2'] = df.apply(lambda x: 10 if x['c1'] == 'Value' else x['c1'], axis = 1)

否则,如果你有一个大的数据框架,请遵循上面的评论中提到的切片技术。

注意这个反转选择的 tilda,它使用熊猫方法(也就是说比 if/else快)。

df.loc[(df['c1'] == 'Value'), 'c2'] = 10
df.loc[~(df['c1'] == 'Value'), 'c2'] = df['c3']

我有一个很大的数据库。Loc []花了太长时间,所以我找到了一种矢量化的方法。回想一下,您可以将列设置为逻辑运算符,因此可以这样做:

file['Flag'] = (file['Claim_Amount'] > 0)

这样就得到了一个布尔值,这也是我想要的,但是你可以把它乘以,比如说,1来得到一个整数。

我相信 图()是非常易读和高效的,例如:

df["c2"] = df["c1"].map(lambda x: 10 if x == 'Value' else x)

我喜欢它,因为如果条件逻辑变得更复杂,你可以把它移动到一个函数中,只是传入那个函数而不是 lambda。

如果您需要将条件逻辑基于多个列,则可以按照其他人的建议使用 Apply ()