【问题标题】:Iterate through data frame遍历数据框
【发布时间】:2021-02-17 11:27:54
【问题描述】:

我的代码提取了一个数据框对象,我想屏蔽该数据框。 如果值

import pandas as pd
XTrain = pd.read_excel('C:\\blahblahblah.xlsx')

for each in XTrain:
  if each <= 15:
    each = 1
  else:
    each = 0

我来自 VBA 和 .NET,所以我知道它不是很 Python,但对我来说似乎超级容易...... 代码遇到错误,因为它遍历 df 标头。 所以我尝试检查类型

for each in XTrain:
  if isinstance(each, str) is False:
    if each <= 15:
      each = 1
    else:
      each = 0

这一次它到达了最终的标头,但没有进入数据帧。 这让我觉得我没有正确循环遍历数据帧? 被难住了几个小时,谁能给我一点帮助?

谢谢!

【问题讨论】:

  • 谢谢,我看到了那篇文章并尝试了 iterrow() 但它不起作用(当时我认为问题出在类型上)。我会重新审视这个。谢谢。
  • np,下面的一些解决方案可能会起作用。
  • itertuples() 将保留数据类型,而 iterrows() 不会。下面介绍的非迭代方法更好;文档here

标签: python pandas dataframe loops isinstance


【解决方案1】:

使用applymap 将函数应用于数据帧的每个元素,使用lambda 编写函数。

df.applymap(lambda x: x if isinstance(each, str) else 1 if x <= 15 else 0)

【讨论】:

    【解决方案2】:

    for each in XTrain 总是循环遍历列名only。 Pandas 就是这样设计的。

    Pandas 允许直接与数字进行比较/算术运算。所以你想要:

     # le is less than or equal to
     XTrains.le(15).astype(int)
    
     # same as
     # (XTrain <= 15).astype(int)
    

    如果您真的想迭代(不要),请记住数据框是二维的。所以是这样的:

    for index, row in df.iterrows():
        for cell in row:
            if cell <= 15:
                # do something
                # cell = 1 might not modify the cell in original dataframe
                # this is a python thing and you will get used to it
            else:
                # do something else
            
    

    【讨论】:

      【解决方案3】:

      设置

      df = pd.DataFrame({'A' : range(0, 20, 2), 'B' : list(range(10, 19)) + ['a']})
      print(df)
      
          A   B
      0   0  10
      1   2  11
      2   4  12
      3   6  13
      4   8  14
      5  10  15
      6  12  16
      7  14  17
      8  16  18
      9  18   a
      

      解决方案pd.to_numeric 避免 str 值和 DataFrame.le 出现问题

      df.apply(lambda x: pd.to_numeric(x, errors='coerce')).le(15).astype(int)
      

      输出

         A  B
      0  1  1
      1  1  1
      2  1  1
      3  1  1
      4  1  1
      5  1  1
      6  1  0
      7  1  0
      8  0  0
      9  0  0
      

      如果你想保留字符串值:

      df2 = df.apply(lambda x: pd.to_numeric(x, errors='coerce'))
      new_df = df2.where(lambda x: x.isna(), df2.le(15).astype(int)).fillna(df)
      print(new_df)
      
      
         A  B
      0  1  1
      1  1  1
      2  1  1
      3  1  1
      4  1  1
      5  1  1
      6  1  0
      7  1  0
      8  0  0
      9  0  a
      

      【讨论】:

        猜你喜欢
        • 2022-01-12
        • 1970-01-01
        • 2016-11-26
        • 2020-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多