【问题标题】:Pandas: drop columns with all NaN'sPandas:删除所有 NaN 的列
【发布时间】:2017-12-22 03:50:18
【问题描述】:

我意识到从数据帧中删除 NaNs 就像 df.dropna 一样简单,但由于某种原因,这对我来说不起作用,我不知道为什么。

这是我的原始数据框:

fish_frame1:                       0   1   2         3   4       5   6          7
0               #0915-8 NaN NaN       NaN NaN     NaN NaN        NaN
1                   NaN NaN NaN  LIVE WGT NaN  AMOUNT NaN      TOTAL
2               GBW COD NaN NaN     2,280 NaN   $0.60 NaN  $1,368.00
3               POLLOCK NaN NaN     1,611 NaN   $0.01 NaN     $16.11
4                 WHAKE NaN NaN       441 NaN   $0.70 NaN    $308.70
5           GBE HADDOCK NaN NaN     2,788 NaN   $0.01 NaN     $27.88
6           GBW HADDOCK NaN NaN    16,667 NaN   $0.01 NaN    $166.67
7               REDFISH NaN NaN       932 NaN   $0.01 NaN      $9.32
8    GB WINTER FLOUNDER NaN NaN       145 NaN   $0.25 NaN     $36.25
9   GOM WINTER FLOUNDER NaN NaN    25,070 NaN   $0.35 NaN  $8,774.50
10        GB YELLOWTAIL NaN NaN        26 NaN   $1.75 NaN     $45.50

下面的代码试图删除所有 NaNs 以​​及任何超过 3 个 NaNs 的列(我认为其中一个或两个都应该有效):

fish_frame.dropna()
fish_frame.dropna(thresh=len(fish_frame) - 3, axis=1)

这会产生:

fish_frame1 after dropna:                       0   1   2         3   4       5   6          7
0               #0915-8 NaN NaN       NaN NaN     NaN NaN        NaN
1                   NaN NaN NaN  LIVE WGT NaN  AMOUNT NaN      TOTAL
2               GBW COD NaN NaN     2,280 NaN   $0.60 NaN  $1,368.00
3               POLLOCK NaN NaN     1,611 NaN   $0.01 NaN     $16.11
4                 WHAKE NaN NaN       441 NaN   $0.70 NaN    $308.70
5           GBE HADDOCK NaN NaN     2,788 NaN   $0.01 NaN     $27.88
6           GBW HADDOCK NaN NaN    16,667 NaN   $0.01 NaN    $166.67
7               REDFISH NaN NaN       932 NaN   $0.01 NaN      $9.32
8    GB WINTER FLOUNDER NaN NaN       145 NaN   $0.25 NaN     $36.25
9   GOM WINTER FLOUNDER NaN NaN    25,070 NaN   $0.35 NaN  $8,774.50
10        GB YELLOWTAIL NaN NaN        26 NaN   $1.75 NaN     $45.50

我是 Pandas 的新手,所以我不确定这是否不起作用,因为我做错了什么,或者我误解了某些东西或滥用了某个功能。感谢任何帮助。

【问题讨论】:

  • .dropna() 不会原地更改 DF - 它返回更改后的 DF...所以您要么必须将其分配回来,如:df = df.dropna() 或明确使用 inplace=True 参数跨度>
  • 哦,我的错。明白了。考虑到我原来的 NaNs 有多少,我是否应该期望该命令生成一个空数据框?
  • 我认为您的第二个命令应该可以工作(因为它以列为目标),但第一个命令将删除带有 NaN 的任何行 - 因为所有行中至少有一个 NaN,它将删除全部。
  • @MaxU: 最好说dropna() 默认情况下inplace=False 所以你需要指定它;但如果你想就地做dropna(..., inplace=True)
  • OP 当您说 “删除所有 NaN” 时,您的真正意思是 “删除所有 NaN 列”。这略有不同。

标签: python pandas dataframe in-place


【解决方案1】:

来自dropna 文档字符串:

删除所有元素都是 NaN 的列:
df.dropna(axis=1, how='all')


   A    B    D
0  NaN  2.0  0
1  3.0  4.0  1
2  NaN  NaN  5

【讨论】:

    【解决方案2】:

    另一种解决方案是在非空位置创建一个具有 True 值的布尔数据框,然后获取具有至少一个 True 值的列。下面的行删除了所有 NaN 值的列。

    df = df.loc[:,df.notna().any(axis=0)]
    

    如果要删除至少有一个缺失 (NaN) 值的列;

    df = df.loc[:,df.notna().all(axis=0)]
    

    这种方法在删除包含空字符串、零或基本上任何给定值的列时特别有用。例如;

    df = df.loc[:,(df!='').all(axis=0)]
    

    删除至少有一个空字符串的列。

    【讨论】:

      【解决方案3】:

      dropna() 默认返回一个数据框(默认为inplace=False 行为),因此需要将其分配给一个新的数据框才能保留在您的代码中。

      例如,

      fish_frame = fish_frame.dropna()
      

      至于为什么您的dropna 返回一个空数据框,我建议您查看 dropna 方法 (https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html) 中的“how”参数。还要记住,axis=0 对应于列,axis=1 对应于行。

      所以要删除所有“NAs”的列,axis=0,how="any" 应该可以解决问题:

      fish_frame = fish_frame.dropna(axis=0, how="any")
      

      最后,“thresh”参数明确指定了发生丢弃需要多少 NA。所以

      fish_frame = fish_frame.dropna(axis=0, thresh=3, how="any") 
      

      应该可以很好地删除任何具有三个 NA 的列。

      此外,正如 Corley 所指出的,how="any" 是默认设置,因此没有必要。

      【讨论】:

        【解决方案4】:

        dropna() 删除空值并返回一个数据帧。将其分配回原始数据帧。

        fish_frame = fish_frame.dropna(axis = 1, how = 'all')
        

        参考您的代码:

        fish_frame.dropna(thresh=len(fish_frame) - 3, axis=1)
        

        这将删除具有 7 个或更多 NaN 的列(假设 len(df) = 10),如果您想删除具有超过 3 个 Nan 的列,就像您提到的那样,thresh 应该等于 3。

        【讨论】:

        • 对。 MaxU 解释了为什么会这样。但特别是对于我的数据框,它在运行fish_frame = fish_frame.dropna() 后生成了一个空数据框。这应该是预期的吗?
        • 尝试传递参数how = 'all'
        猜你喜欢
        • 2018-10-29
        • 2021-02-20
        • 2014-09-28
        • 2017-05-11
        • 1970-01-01
        • 2012-06-07
        • 1970-01-01
        • 2021-12-31
        • 1970-01-01
        相关资源
        最近更新 更多