在数据框中用作运算符的列表的动态长度
Dynamic lengths of list applied as operators in dataframe
如果我有这样的列表:
myList = ['a', 'b', 'c']
和 df 一样
并且我想在基于 a、b、c 的 df 中创建一个新列,我可以这样做:
df['new_col_1'] = df[myList[0]] & df[myList[1]] & df[myList[2]]
每个单元格中都存在一个布尔值,因此结果是 True/False。
问题是有时 'myList' 的长度可能不是 3,而是 2、4 等。有没有简单的方法来补偿 myList 的不同长度?
此外,一旦 'new_col_1' 设置为 True(在本例中仅适用于 'mnl'),则应将其所有列(因此 a、b、c)设置为FALSE,因为 'new_col_1' 现在是 TRUE。结果应该是:
一个简单的 for
循环就足够了。
代码高手解决方案将使用 reduce
from functools import reduce
import operator
df['new_col_1'] = reduce(operator.and_, map(df.__getitem__, myList))
首先让我们根据您的示例创建数据框和列表:
import pandas as pd
df = pd.DataFrame(
[
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 0],
[1, 1, 1, 0, 1],
],
index=["abc", "def", "ghi", "jkl", "mnl"],
columns=list("abcde")
).applymap(bool)
my_list = ['a', 'b', 'c']
那我们把问题分成两部分
第 1 部分:创建 new_col
您基本上需要从 my_list
中取出所有列并按行执行 and
操作。您可以使用 all(axis=1)
:
df["new_col"] = df[my_list].all(axis=1)
结果将是:
a b c d e new_col
abc False False False False False False
def False False False False True False
ghi False False False True False False
jkl False False False False False False
mnl True True True False True True
第 2 部分:根据 new_col
更新 table
这可以通过 loc
运算符来完成。我们想影响 new_col
为 True
的所有行,并将 False
设置为 my_list
:
中的列
df.loc[df["new_col"], my_list] = False
结果将是:
a b c d e new_col
abc False False False False False False
def False False False False True False
ghi False False False True False False
jkl False False False False False False
mnl False False False False True True
这是使用 df.dot
and np.where
的另一种方法(数据由@villoro 提供)
c = df.dot(df.columns).eq(''.join(my_list)) #assuming all the columns are booleans
final = pd.DataFrame(np.where(c[:,None],False,df),columns=df.columns,index=df.index)
.assign(new_col1=c)
print(final)
a b c d e new_col1
abc False False False False False False
def False False False False True False
ghi False False False True False False
jkl False False False False False False
mnl False False False False False True
如果我有这样的列表:
myList = ['a', 'b', 'c']
和 df 一样
并且我想在基于 a、b、c 的 df 中创建一个新列,我可以这样做:
df['new_col_1'] = df[myList[0]] & df[myList[1]] & df[myList[2]]
每个单元格中都存在一个布尔值,因此结果是 True/False。
问题是有时 'myList' 的长度可能不是 3,而是 2、4 等。有没有简单的方法来补偿 myList 的不同长度?
此外,一旦 'new_col_1' 设置为 True(在本例中仅适用于 'mnl'),则应将其所有列(因此 a、b、c)设置为FALSE,因为 'new_col_1' 现在是 TRUE。结果应该是:
一个简单的 for
循环就足够了。
代码高手解决方案将使用 reduce
from functools import reduce
import operator
df['new_col_1'] = reduce(operator.and_, map(df.__getitem__, myList))
首先让我们根据您的示例创建数据框和列表:
import pandas as pd
df = pd.DataFrame(
[
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 0],
[1, 1, 1, 0, 1],
],
index=["abc", "def", "ghi", "jkl", "mnl"],
columns=list("abcde")
).applymap(bool)
my_list = ['a', 'b', 'c']
那我们把问题分成两部分
第 1 部分:创建 new_col
您基本上需要从 my_list
中取出所有列并按行执行 and
操作。您可以使用 all(axis=1)
:
df["new_col"] = df[my_list].all(axis=1)
结果将是:
a b c d e new_col
abc False False False False False False
def False False False False True False
ghi False False False True False False
jkl False False False False False False
mnl True True True False True True
第 2 部分:根据 new_col
这可以通过 loc
运算符来完成。我们想影响 new_col
为 True
的所有行,并将 False
设置为 my_list
:
df.loc[df["new_col"], my_list] = False
结果将是:
a b c d e new_col
abc False False False False False False
def False False False False True False
ghi False False False True False False
jkl False False False False False False
mnl False False False False True True
这是使用 df.dot
and np.where
的另一种方法(数据由@villoro 提供)
c = df.dot(df.columns).eq(''.join(my_list)) #assuming all the columns are booleans
final = pd.DataFrame(np.where(c[:,None],False,df),columns=df.columns,index=df.index)
.assign(new_col1=c)
print(final)
a b c d e new_col1
abc False False False False False False
def False False False False True False
ghi False False False True False False
jkl False False False False False False
mnl False False False False False True