【问题标题】:How to use loop for columns in a dataframe in Python如何在 Python 中对数据框中的列使用循环
【发布时间】:2021-12-14 09:07:24
【问题描述】:

我有以下代码,但它有点重复。谁能告诉我如何将这些语句放入循环中。数据框由 T1 到 T12 和 P1 到 P12 的列组成。在这里,我只展示了每个条件的 3 个语句。

我有以下代码,但它有点重复。谁能告诉我如何将这些语句放入循环中。数据框由 T1 到 T12 和 P1 到 P12 的列组成。在这里,我只展示了每个条件的 3 个语句。

第一个条件

df['P1'] = df.apply(lambda row: 1 if row['P1'] >= 5 * row['T1'] else 0, axis=1)
df['P2'] = df.apply(lambda row: 1 if row['P2'] >= 5 * row['T2'] else 0, axis=1)
df['P3'] = df.apply(lambda row: 1 if row['P3'] >= 5 * row['T3'] else 0, axis=1)

第二个条件

df['T1'] = df.apply(lambda row: 1 if row['T1'] >= 7 else 0, axis=1)
df['T2'] = df.apply(lambda row: 1 if row['T2'] >= 7 else 0, axis=1)
df['T3'] = df.apply(lambda row: 1 if row['T3'] >= 7 else 0, axis=1)

第三个条件

df['G1'] = np.where((df['T1']==1) & (df['P1'] ==1), 1, 0)
df['G2'] = np.where((df['T2']==1) & (df['P2'] ==1), 1, 0)
df['G3'] = np.where((df['T3']==1) & (df['P3'] ==1), 1, 0)

【问题讨论】:

    标签: python pandas for-loop


    【解决方案1】:

    当尝试将代码汇总到循环中时,请查看发生了什么变化,以及它是如何做到的。这是您的前三个陈述:

    df['P1'] = df.apply(lambda row: 1 if row['P1'] >= 5 * row['T1'] else 0, axis=1)
    df['P2'] = df.apply(lambda row: 1 if row['P2'] >= 5 * row['T2'] else 0, axis=1)
    df['P3'] = df.apply(lambda row: 1 if row['P3'] >= 5 * row['T3'] else 0, axis=1)
    

    让我们暂时简化一下:

    df['P1'] = func("P1", "T1")
    df["P2"] = func("P2", "T2")
    

    我删除了所有不变的东西。这些字符串参数是什么,每次都增加1。所以我们可以这样卷起来:

    for i in range(1,4): # integer between 1 and 3, not 4!
        p = f"p{i}"
        t = f"t{i}"
        print("p", p, "t", t)
    

    实际运行这段代码!你看到它是如何产生我们需要的参数的吗?所以现在我们回家了:

    for i in range(1, 3):
        p = f"p{1}"
        t = f"t{1}"
        df[p] = df.apply(lambda row: 1 if row[p] >= 5 * row[t] else 0, axis=1)
    

    您的其他条件都可以类似地汇总。


    在这种情况下,正如其他答案所述,可以在 pandas 中隐式编写此循环。 (即对其进行矢量化:我不知道这实际上是运行循环还是正确矢量化,因为我还没有研究过 pandas 是如何实现的。)但仍然值得了解如何明确地做到这一点。

    【讨论】:

      【解决方案2】:

      不要在 apply 中使用循环,因为这里存在矢量化更快的替代方案 - 比较所有过滤的行并通过将掩码转换为整数将 True, False 转换为 1,0

      np.random.seed(2021)
      df = pd.DataFrame(np.random.randint(10, size=(5, 9)))
      df.columns = ['P1','P2','P3','T1','T2','T3','G1','G2','G3']
      print (df)
         P1  P2  P3  T1  T2  T3  G1  G2  G3
      0   4   5   9   0   6   5   8   6   6
      1   6   6   1   5   7   1   1   5   2
      2   0   3   1   0   2   6   4   8   5
      3   1   6   7   5   6   9   5   6   9
      4   2   4   3   9   2   8   5   3   1
      
      #for filter all columns starting by P, T, G
      p = df.filter(regex='^P').columns
      t = df.filter(regex='^T').columns
      g = df.filter(regex='^G').columns
      
      #for filter all columns by lists
      p = ['P1','P2','P3']
      t = ['T1','T2','T3']
      g = ['G1','G2','G3']
      

      df[p] = (df[p] >= 5 * df[t].to_numpy()).astype(int)
      
      df[t] = (df[t] >= 7).astype(int)
      
      df[g] = ((df[t] == 1) & (df[p].to_numpy() == 1)).astype(int)
      print (df)
         P1  P2  P3  T1  T2  T3  G1  G2  G3
      0   1   0   0   0   0   0   0   0   0
      1   0   0   0   0   1   0   0   0   0
      2   1   0   0   0   0   0   0   0   0
      3   0   0   0   0   0   1   0   0   0
      4   0   0   0   1   0   1   0   0   0
      

      【讨论】:

        【解决方案3】:

        我想你可以试试这个..

        indexP = ['P1','P2','P3']
        indexT = ['T1','T2','T3']
        indexG = ['G1','G2','G3']
        
        for x in indexP :
            df[x] = (df[x] >= 5 * df[x])
        for y in indexT :
            df[y] = (df[y] >= 7)
        for z in indexG
            df[z] = ((df[z]==1) & (df[z] ==1))
        

        【讨论】:

          猜你喜欢
          • 2019-03-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-14
          • 2023-04-05
          • 1970-01-01
          • 2021-06-13
          相关资源
          最近更新 更多