【问题标题】:Dynamic lengths of list applied as operators in dataframe列表的动态长度作为数据框中的运算符应用
【发布时间】:2020-01-22 14:50:04
【问题描述】:

如果我有这样的列表:

myList = ['a', 'b', 'c']

和 df 一样

我想在基于 a、b、c 的 df 中创建一个新列,我可以这样做:

df['new_col_1'] = df[myList[0]] & df[myList[1]] & df[myList[2]]

每个单元格中都有一个布尔值,因此结果是真/假。

问题是有时“myList”的长度可能不是 3,而是 2、4 等。是否有一种简单的方法来补偿不同长度的 myList?

此外,一旦 'new_col_1' 设置为 True(在这种情况下仅适用于 'mnl'),则应该将其所有列(如 a、b、c)设置为 FALSE,因为 'new_col_1'现在是 TRUE。结果应该是:

【问题讨论】:

  • 您能否创建一个示例数据框并向我们展示预期的输出应该如何?
  • @anky_91:刚刚添加...

标签: python-3.x pandas dataframe operators


【解决方案1】:

首先让我们根据您的示例创建数据框和列表:

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 更新表

这可以通过locoperator 来完成。我们希望影响new_colTrue 的所有行并将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

【讨论】:

  • 我认为这看起来非常像我需要的解决方案 - 谢谢!只有一件事(我应该给出一个更好的例子):假设单元格“mnl / e”为真,我不希望将其设置为假,而是保持原样。我该怎么做?
  • 欢迎您。我将答案更改为仅将 my_list 中的列设置为 False。如果此答案解决了您的问题,您可以将其标记为已接受的答案。
  • 谢谢,在您更改之前我已经自己解决了这个问题,我将您的答案标记为正确的。
【解决方案2】:

一个简单的for 循环就足够了。

代码高尔夫球手解决方案将使用reduce

from functools import reduce
import operator

df['new_col_1'] = reduce(operator.and_, map(df.__getitem__, myList))

【讨论】:

    【解决方案3】:

    这是使用df.dotnp.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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-13
      • 1970-01-01
      • 1970-01-01
      • 2016-10-11
      • 2011-08-15
      • 2015-05-28
      • 2014-12-09
      • 2018-01-20
      相关资源
      最近更新 更多