【问题标题】:Looping over columns in Pandas循环遍历 Pandas 中的列
【发布时间】:2021-01-29 01:34:53
【问题描述】:

我试图将每两列除以数据集中的最后两列。例如,我想将column[0]和column[2]除以column[-2],然后将结果分别存储在column[0]和column[2]中。

理想情况下,我想要的是从中获得:

   fra1  ger1   fra2  ger2  fra pop  ger pop
0    12    14    525    52       14       14

类似这样的:

           fra1          ger1          fra2          ger2  
0    12/fra pop    14/ger pop   525/fra pop    52/ger pop

也就是说,我想通过将每个国家/地区的值除以其人口来创建一个新的数据框(保留原始列标签)。 对每一列手动执行此操作会占用真实数据集的太多时间,而且我无法弄清楚如何运行循环。

有人可以帮忙吗? 非常感谢!

【问题讨论】:

    标签: pandas loops indexing


    【解决方案1】:

    这是一个使用 pandas 的多索引和广播的解决方案。多索引将国家和指标放在两个单独的列标签级别。广播可让您将每个德国(或法国)指标除以德国(或法国)人口。

    from io import StringIO
    import pandas as pd
    
    # add 2nd row to validate results below
    t = '''
       fra1  ger1   fra2  ger2  fra pop  ger pop
    0    12    14    525    52       14       14
    1     2    3       4     5        6        7
    '''
    df = pd.read_csv(StringIO(t), sep='\s\s+', engine='python')
    
    # create hierarchical index (i.e., multi-index)
    midx = [('france', 'm1'), ('germany', 'm2'),
            ('france', 'm2'), ('germany', 'm2'),
            ('france', 'pop'), ('germany', 'pop')]
    midx = pd.MultiIndex.from_tuples(midx, names=['country', 'metric'])
    df.columns = midx
    
    # create `metrics` data frame (excludes population)
    metrics = df.loc[:, (slice(None), ['m1', 'm2'])]
    
    # create population data frame (and remove one level of index)
    pop = df.loc[:, (slice(None), 'pop')].droplevel(level='metric', axis=1)
    
    result = metrics.div(pop, level='country')
    print(result)
    
    country    france   germany     france   germany
    metric         m1        m2         m2        m2
    0        0.857143  1.000000  37.500000  3.714286
    1        0.333333  0.428571   0.666667  0.714286
    

    更多信息在这里:https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html

    【讨论】:

      【解决方案2】:

      我想我也找到了解决办法:

      divisor = df.iloc[:,-2:]
      for index, column in enumerate(df):
          values = df[column]
          if index < 2:
              num1 = values
              df[column] = num1/divisor.iloc[:,index]
          if 1 < index < 3:
              num2 = values
              df[column] = num2/divisor.iloc[:,index-2]
      

      【讨论】:

      • 您得到的结果与您在问题中描述的fra1ger1 不同。很容易看出 ger1 在您的示例数据中应该是 1.0
      • 是的,这是真的。我的错误是在报告样本数据时我删除了观察结果,而我发布的代码并没有说明这一点。我会马上解决的
      【解决方案3】:

      如果你改变你原来的组织,你可以更容易地做到这一点,但从这一点开始,最好只使用一些逻辑来确定前缀,然后为每个子组执行划分,然后将结果与concat 加入结束。

      # Prefix is everything before `' pop'`
      prefixes = [x.rsplit(' ', 1)[0] for x in df.columns if x.endswith('pop')]
      #['fra', 'ger']    
      
      l = []
      for pref in prefixes:
          l.append(df[[x for x in df.columns if x.startswith(pref) and not x.endswith('pop')]]
                      .divide(df[f'{pref} pop'], axis=0))
      
      res = pd.concat(l, axis=1)
      #       fra1  fra2  ger1      ger2
      #0  0.857143  37.5   1.0  3.714286
      

      【讨论】:

      • 感谢您的提示。然而,给定原始标签的原始数据集无法实现此方法。
      • @Luca 我不确定我理解你的意思,或者考虑到你提供的示例数据,为什么它会失败
      • 对不起,我的回答不清楚。我随机创建了一个与原始数据集具有相同特征的数据集,但报告了我任意设置的变量名称。在原始数据集中,我有不以国家名称开头的变量名称。
      【解决方案4】:

      您可以使用df.columnsslicing 选择适合您的用例的列

      设置数据框

      import pandas as pd
      import io
      
      t = '''
         fra1  ger1   fra2  ger2  fra pop  ger pop
      0    12    14    525    52       14       14'''
      df = pd.read_csv(io.StringIO(t), sep='\s\s+', engine='python')
      df
      

      输出:

         fra1  ger1  fra2  ger2  fra pop  ger pop
      0    12    14   525    52       14       14
      

      必须根据您的实际数据调整要划分的列名的切片 [:4] [-2:] 和乘法因子 2

      df[df.columns[:4]].div(df[df.columns[-2:].tolist()*2].values)
      

      输出:

             fra1  ger1  fra2      ger2
      0  0.857143   1.0  37.5  3.714286
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-24
        • 2016-05-03
        • 1970-01-01
        • 2021-03-06
        • 2019-11-14
        • 2021-09-12
        • 1970-01-01
        • 2010-12-09
        相关资源
        最近更新 更多