【问题标题】:Build new dataframe with for loop given condition in another dataframe在另一个数据框中使用for循环给定条件构建新数据框
【发布时间】:2018-11-22 00:50:55
【问题描述】:

这是我要遍历的数据框。为countriesyear 设置了索引。

                            ISO_code    gini    ECONOMIC FREEDOM    rank    quartile    1a_government_consumption
        countries   year                                                                                    
        Argentina   1980    ARG         40.8    4.25    80.0    4.0 6.911765
                    1995    ARG         48.9    6.95    37.0    2.0 8.058824
                    2000    ARG         51.1    7.34    37.0    2.0 6.877627
                    2001    ARG         53.3    6.84    56.0    2.0 6.752473
                    2002    ARG         53.8    6.28    79.0    3.0 6.905961
                    2003    ARG         50.7    6.16    86.0    3.0 7.264992
        Bolivia     1980    BOL         40.8    4.25    80.0    4.0 6.911765
                    1985    BOL         48.9    6.95    37.0    2.0 8.058824
                    1995    BOL         51.1    7.34    37.0    2.0 6.877627
                    2000    BOL         53.3    6.84    56.0    2.0 6.752473
                    2001    BOL         53.8    6.28    79.0    3.0 6.905961
                    2002    BOL         50.7    6.16    86.0    3.0 7.264992
        Chile       1985    CHI         40.8    4.25    80.0    4.0 6.911765
                    1990    CHI         48.9    6.95    37.0    2.0 8.058824
                    1995    CHI         51.1    7.34    37.0    2.0 6.877627
                    1999    CHI         53.3    6.84    56.0    2.0 6.752473
                    2002    CHI         53.8    6.28    79.0    3.0 6.905961
                    2003    CHI         50.7    6.16    86.0    3.0 7.264992

我想创建一个 for 循环,返回这样的数据框:

countries    change gini    change ef                                                                 
Argentina    +              +
Bolivia      -              +
Chile        -              -
  1. countries 只是前一个数据框中国家名称的列。

  2. change gini 应该是每个国家/地区的 gini 列的最后一个值与最近一个值之间的百分比差异。如果百分比增加为正,则应显示+;如果是 negativa,那么它应该显示 -

  3. change ef 遵循与新数据框中的 change gini 相同的逻辑,唯一的区别是用于计算百分比变化的值来自原始数据框中的 ECONOMIC FREEDOM 列。

【问题讨论】:

    标签: python pandas loops dataframe for-loop


    【解决方案1】:

    您可以通过分组函数轻松实现此目的。
    不幸的是,您的数据集中三个国家的第一个和最后一个值相同,因此结果也是相同两个值的三倍。
    (也许样本数据有问题?)

    首先按国家/地区对数据框进行分组,然后只选择感兴趣的两列:

    grpd = df.groupby('countries')['gini', 'ECONOMIC FREEDOM']
    

    使用此Groupby-Object,您可以将函数应用于由分组功能分隔的数据子集,在您的情况下为countries
    例如。要获得每个组中的最后一个值,只需要求

    grpd.last()
    
               gini  ECONOMIC FREEDOM
    countries                        
    Argentina  50.7              6.16
    Bolivia    50.7              6.16
    Chile      50.7              6.16
    

    或相应地用于每组的第一行

    grpd.first()
    
               gini  ECONOMIC FREEDOM
    countries                        
    Argentina  40.8              4.25
    Bolivia    40.8              4.25
    Chile      40.8              4.25
    

    为了计算最后一个相对于第一个的变化百分比,你可以简单地写

    (grpd.last() - grpd.first()) / grpd.first()
    
                    gini  ECONOMIC FREEDOM
    countries                             
    Argentina  0.242647         0.449411
    Bolivia    0.242647         0.449411
    Chile      0.242647         0.449411
    

    编辑:
    输出也可以被格式化,例如喜欢:

    df_change = (grpd.last() - grpd.first()) / grpd.first()
    
    df_change.applymap(lambda x: str.format('{:+.1f%}', x))
    
                 gini ECONOMIC FREEDOM
    countries                         
    Argentina  +24.3%           +44.9%
    Bolivia    +24.3%           +44.9%
    Chile      +24.3%           +44.9%
    

    EDIT2:
    仅用于标志:

    df_change.applymap(lambda x: ['-', ' ', '+'][np.sign(x).astype(int)+1])
    
              gini ECONOMIC FREEDOM
    countries                      
    Argentina    +                +
    Bolivia      +                +
    Chile        +                +
    

    【讨论】:

      【解决方案2】:

      countriesginiECONOMIC FREEDOM 列为每个国家/地区创建空列表并附加所需的值。

          countries = []
          gini = []
          efw = []
          for i in new_df.index.levels[0]:
              countries.append(i)
              country = new_df.loc[i]
              country = country.reset_index()
              x = country.iloc[0].tolist()
              y = country.iloc[-1].tolist()
              change_g = (((y[2] / x[2]) - 1) * 100)
              change_e = (((y[3] / x[3]) - 1) * 100)
              gini.append(change_g)
              efw.append(change_e)
      

      然后做一个for循环。对于每个数字,您附加一个 +-

      g = []
      e = []
      for n in gini:
          if n > 0:
              g.append("+")
          g.append("-")
      
      for f in efw:
          if f > 0:
              e.append("+")
          e.append("-")
      

      然后创建一个包含countriesge 列表的数据框。

      tuples = list(zip(countries,g,e))
      changes = pd.DataFrame(tuples, columns=['Country','Change in Gini', "Change in Economic Freedom"])
      

      【讨论】:

      • 这读起来更像是通用 Python,而不是 pandas 风格的 Python。考虑groupby 和矢量化(非循环)处理。
      猜你喜欢
      • 2017-09-30
      • 2011-09-07
      • 2014-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-22
      • 2018-04-04
      • 1970-01-01
      相关资源
      最近更新 更多