【问题标题】:Pandas apply filter dynamicallyPandas 动态应用过滤器
【发布时间】:2020-11-21 12:29:26
【问题描述】:

我有一个复杂的问题要解决。 我有一个像这样的数据框:

所需的输出是:

所以它基本上是在逻辑上分组,即)

对于第一行:它只有 a 和 a 因此只有 1 在 a 下,其余为 0

对于第二行:它是 a 和 b,因此是 1 和 1,其余是 0 等等

接下来基于新的df:

对于每一行,我必须过滤一个数据框(比如 df3),例如:

第一行:df3.loc[(df3['name']=='a')]['flag'].count()

第二行:df3.loc[(df3['name']=='a') & (df3['name']=='b')]['flag'].count()

第三行:df3.loc[(df3['name']=='a') & (df3['name']=='b') & & (df3['name']=='c ')]['flag'].count()

知道如何实现吗?

我正在尝试循环生成这些过滤器,然后应用于 df3 数据帧

【问题讨论】:

  • 所以逻辑仅用于a 列中的第一行1a 列中的第一行bb 列中的1,仅b 列中的第一行c@987654334 @ 在c 列中?所有其他行都是从1,11,1,1,1
  • 没错。就像一个逻辑“和”条件
  • for each row, i have to filter a dataframe(say df3) ? df3 看起来怎么样?
  • df3 是另一个 df,它有一列包含像 a,b,c,d 这样的数据,我将使用它来根据条件进行过滤
  • 刚刚编辑了我的帖子并为 df3 添加了结构,我将使用 df3 来过滤基于使用 df1 动态生成的过滤器的记录

标签: python pandas filter


【解决方案1】:

你可以使用numpy:

df1 = pd.DataFrame(0, index=list('aaaabbbb'), columns=list('abcd'))
print (df1)
   a  b  c  d
a  0  0  0  0
a  0  0  0  0
a  0  0  0  0
a  0  0  0  0
b  0  0  0  0
b  0  0  0  0
b  0  0  0  0
b  0  0  0  0

首先由numpy.trilnumpy.ones创建下三角矩阵:

size = len(df1.columns)
         
a = np.tril(np.ones((size, size), dtype=int))
print (a)
[[1 0 0 0]
 [1 1 0 0]
 [1 1 1 0]
 [1 1 1 1]]

然后用numpy.fill_diagonal填充对角线值到1

b = np.zeros((size, size), dtype=int)
np.fill_diagonal(b, 1)
print (b)
[[1 0 0 0]
 [0 1 0 0]
 [0 0 1 0]
 [0 0 0 1]]

通过使用numpy.tile 的列数重复数组a 并通过使用数组b 的值索引来覆盖每个size 行:

c = np.tile(a, (size, 1))
c[::size] = b
print (c)
[[1 0 0 0]
 [1 1 0 0]
 [1 1 1 0]
 [1 1 1 1]
 [0 1 0 0]
 [1 1 0 0]
 [1 1 1 0]
 [1 1 1 1]
 [0 0 1 0]
 [1 1 0 0]
 [1 1 1 0]
 [1 1 1 1]
 [0 0 0 1]
 [1 1 0 0]
 [1 1 1 0]
 [1 1 1 1]]

最后转换为DataFrame

df = pd.DataFrame(c, columns=df1.columns, index = np.repeat(df1.columns, size))
print (df)
   a  b  c  d
a  1  0  0  0
a  1  1  0  0
a  1  1  1  0
a  1  1  1  1
b  0  1  0  0
b  1  1  0  0
b  1  1  1  0
b  1  1  1  1
c  0  0  1  0
c  1  1  0  0
c  1  1  1  0
c  1  1  1  1
d  0  0  0  1
d  1  1  0  0
d  1  1  1  0
d  1  1  1  1

【讨论】:

  • 行得通!!!第一项任务完成:) 非常感谢
  • @AkshatShreemali - 不幸的是仍然不明白第二个任务。你能解释一下为什么0df3 中的前两行和第三行是df3?或者换句话说,通过上述解决方案,df3 的预期输出是什么?
  • 首先,非常感谢,非常感谢您的帮助。所以对于 df3,我只需要根据新数据框创建的条件迭代地过滤其中的数据。例如:新数据帧的第一行将包含按条件过滤的 df3 记录:df3['name']=='a' 然后第二行将是 df3['name'='a' 和 'b' 然后是第三行行将是 df3['name']=='a 和 b 和 c 那样。 df3 将仅用于基于“和”过滤器进行过滤
  • 如果我们可以根据创建的数据框动态生成这些过滤器。我无法动态生成这些过滤器。
  • @AkshatShreemali - 不幸的是仍然不明白第二个任务。您能解释一下为什么 df3 中的前 2 行为 0,第三行为 1 吗?
【解决方案2】:

我能够做到这一点。 所以在数据框上使用'eval'。 我能够使用 for 循环生成一个字符串,并且能够在 eval 函数中传递该字符串。 例如:

for i in range(0,len(df.columns)):
        if len(df.columns[i])==1:
            uu=[]
            st = column + "==" +"'"+str(df.columns[i][0])+"'"
            #print(column)
            uu.append(st)
            uu2 = ' | '.join([str(elem) for elem in uu]) 
            # uu2 string will directly go to df to get evaluated
            aa = df[df.eval(uu2)]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    • 1970-01-01
    • 2016-09-17
    相关资源
    最近更新 更多