【问题标题】:Apply for loop in multiple dataframe for multiple columns?在多个数据框中为多列申请循环?
【发布时间】:2021-07-19 21:44:35
【问题描述】:

数据框如下:如果年龄超过 100,我想将数据框值更改为“死亡”。

import pandas as pd
raw_data = {'age1': [23,45,210],'age2': [10,20,150],'name': ['a','b','c']}
df = pd.DataFrame(raw_data, columns = ['age1','age2','name'])

raw_data = {'age1': [80,90,110],'age2': [70,120,90],'name': ['a','b','c']}
df2 = pd.DataFrame(raw_data, columns = ['age1','age2','name'])

期望的结果

df=
    age1    age2    name
0   23      10       a
1   45      20       b
2   dead    dead     c

df2=
    age1    age2    name
0   80      70       a
1   90      dead     b
2   dead    90       c

我正在尝试这样的事情:

col_list=['age1','age2']
df_list=[df,df2]

def dead(df):
  for df in df_list:
    if df.columns in col_list:
      if df.columns >=100:
        return 'dead'
    else:
      return df.columns

df.apply(dead)

显示错误: 具有多个元素的数组的真值是不明确的。使用 a.any() 或 a.all()

我正在寻找一个适用于所有数据帧的循环。

请更正我的功能以供将来学习:)

【问题讨论】:

  • 错误是说你试图在数组上使用逻辑而不是它不能做的值。例如,如果值 == 0;只要它不是一个值数组,这对价值是有好处的。
  • 你也有 def dead(df) 但也在 df_list 中使用 df。因此,您有 df 两次。这很混乱,不建议这样做。它可能会导致问题。更改其中一个及其相关变量。
  • 另外,使用 where 子句代替遍历 pandas 数据帧。遍历 pandas 的规模非常可怕。 geeksforgeeks.org/python-pandas-dataframe-where
  • 谢谢,我实际上是在寻找一个 for 循环,因为我无法在数据框列表上应用这个乐趣。

标签: python pandas dataframe data-science


【解决方案1】:

使用您展示的示例,请尝试以下操作。分别使用pandas、numpy的filternp.where函数。

c = df.filter(regex='age\d+').columns
df[c] = np.where(df[c].ge(100),'dead',df[c])
df


where 的替代方法:

c=df.filter(like='age').columns
df[c] = df[c].where(~df['c'].ge(100),'dead')

解释:

  • 在 c 变量中获取具有相同名称的列,例如 age
  • 然后使用np.where 检查各个(所有年龄列)是否为greeter/等于100,如果是则将其设置为死或保持原样。

【讨论】:

  • 你可以在 df 本身上做一个更快的地方,对吗?
  • @JustinOberle、np.wherewhere 工作相同(逻辑明智)。有时np.where 也更快。
  • @JustinOberle,我也在这里添加了where 的答案,以及文档链接和解释,干杯。
【解决方案2】:

我做了以下事情:

col_list=['age1','age2']
df_list=[df,df2]

for d in df_list:
    for c in col_list:
        d.loc[d[c]>100, c] = 'dead'

【讨论】:

    【解决方案3】:

    一种可能的解决方案是使用 Pandas 的 mask,它类似于 if-else,但矢量化了。

    def dead(df):
        col_list = ['age1', 'age2']
        df = df.copy()
        temporary = df.filter(col_list)
        temporary = temporary.mask(temporary >= 100, "dead")
        df.loc[:, col_list] = temporary
        return df
    

    对数据框应用函数:

    df.pipe(dead)
     
       age1  age2 name
    0    23    10    a
    1    45    20    b
    2  dead  dead    c
    

    【讨论】:

      【解决方案4】:

      #inspired by @jib 和 @ravinder

      col_list=['age1','age2']
      df_list=[df,df2]
      
      for d in df_list:
        for c in col_list:
          d[c]=np.where(d[c]>100,'dead',d[c])
      df #or df2
      

      输出:

         age1  age2 name
      0    23    10    a
      1    45    20    b
      2  dead  dead    c
      

      【讨论】:

        【解决方案5】:

        你可以这样做:

        def check_more_than_100(x):
            v = None
            try:
                v = int(x)
            except:
                pass
            if v is not None:
                return (v > 100)
            return (False)
            
        df['age1'] = df['age1'].apply(lambda x : 'dead' if check_more_than_100(x) else x)
        df['age2'] = df['age2'].apply(lambda x : 'dead' if check_more_than_100(x) else x)
        
        df2['age1'] = df2['age1'].apply(lambda x : 'dead' if check_more_than_100(x) else x)
        df2['age2'] = df2['age2'].apply(lambda x : 'dead' if check_more_than_100(x) else x)
        

        这应该处理非 int 值(如果有)。

        【讨论】:

          【解决方案6】:

          我用this answer 回答了一个类似的问题。基本上你可以使用 numpy 中的 .where() 函数来根据条件进行设置。

          import pandas as pd
          import numpy as np
          raw_data = {'age1': [23,45,210],'age2': [10,20,150],'name': ['a','b','c']}
          df = pd.DataFrame(raw_data, columns = ['age1','age2','name'])
          
          raw_data = {'age1': [80,90,110],'age2': [70,120,90],'name': ['a','b','c']}
          df2 = pd.DataFrame(raw_data, columns = ['age1','age2','name'])
          
          col_list=['age1','age2']
          df_list=[df,df2]
          
          def dead(df_list, col_list):
              for df in df_list:
                  for col in col_list:
                      df[col] = np.where(df[col] >= 100, "dead", df[col])
              return df_list
          
          
          df
          
          dead([df], col_list)
          

          【讨论】:

            【解决方案7】:

            提取数字列,然后使用 numpy where -

            df_cols  = df._get_numeric_data().columns.values
            df2_cols  = df2._get_numeric_data().columns.values
            df[df_cols] = np.where(df[df_cols].to_numpy() > 100, 'dead', df[df_cols])
            df2[df2_cols] = np.where(df2[df2_cols].to_numpy() > 100, 'dead', df2[df2_cols])
            

            【讨论】:

              猜你喜欢
              • 2015-05-04
              • 1970-01-01
              • 2017-01-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多