从 pandas 数据框中的多行中提取非 nan 值

Posted

技术标签:

【中文标题】从 pandas 数据框中的多行中提取非 nan 值【英文标题】:To extract non-nan values from multiple rows in a pandas dataframe 【发布时间】:2013-04-07 16:14:41 【问题描述】:

我正在研究几个出租车数据集。我使用 pandas 将所有数据集连接到一个数据帧中。

我的数据框看起来像这样。

                     675                       1039                #and rest 125 taxis
                     longitude     latitude    longitude    latitude
date
2008-02-02 13:31:21  116.56359  40.06489       Nan          Nan
2008-02-02 13:31:51  116.56486  40.06415       Nan          Nan
2008-02-02 13:32:21  116.56855  40.06352       116.58243    39.6313
2008-02-02 13:32:51  116.57127  40.06324       Nan          Nan
2008-02-02 13:33:21  116.57120  40.06328       116.55134    39.6313
2008-02-02 13:33:51  116.57121  40.06329       116.55126    39.6123
2008-02-02 13:34:21  Nan        Nan            116.55134    39.5123

其中 675,1039 是出租车 ID。基本上一共有127辆出租车,对应的经纬度列起来了。

我有几种方法可以提取一行的非空值。

df.ix[k,df.columns[np.isnan(df.irow(0))!=1]]
              (or)
df.irow(0)[np.isnan(df.irow(0))!=1]
              (or)
df.irow(0)[np.where(df.irow(0)[df.columns].notnull())[0]]

上述任何命令都会返回,

675   longitude    116.56359
      latitude     40.064890 
4549  longitude    116.34642
      latitude      39.96662
Name: 2008-02-02 13:31:21

现在我想从前几行中提取所有非空值(比如从第 1 行到第 6 行)。

我该怎么做?

我大概可以把它循环起来。但我想要一种非循环的方式。

欢迎任何帮助,建议。 谢谢你的建议! :)

【问题讨论】:

【参考方案1】:
df.ix[1:6].dropna(axis=1)

请注意,irow 将在下一版 pandas 中被弃用。新方法,用法更清晰,替换掉吧。

http://pandas.pydata.org/pandas-docs/dev/indexing.html#deprecations

【讨论】:

非常感谢您提供的信息。但显然你提到的命令不是我想要的:( :( 在一行中,我需要提取所有非空值。=> 对于几行,没有迭代,我可以用更紧凑的方式来做是问题。谢谢你这么多回复:)【参考方案2】:

在 0.11 中(0.11rc1 现已推出),这很容易使用 .iloc 首先选择前 6 行,然后 dropna 删除带有 nan 的任何行(您也可以将一些选项传递给 dropna 来控制正是您要考虑的列)

我意识到你想要 1:6,我的回答是 0:6....

In [8]: df = DataFrame(randn(10,3),columns=list('ABC'),index=date_range('20130101',periods=10))

In [9]: df.ix[6,'A'] = np.nan

In [10]: df.ix[6,'B'] = np.nan

In [11]: df.ix[2,'A'] = np.nan

In [12]: df.ix[4,'B'] = np.nan

In [13]: df.iloc[0:6]
Out[13]: 
                   A         B         C
2013-01-01  0.442692 -0.109415 -0.038182
2013-01-02  1.217950  0.006681 -0.067752
2013-01-03       NaN -0.336814 -1.771431
2013-01-04 -0.655948  0.484234  1.313306
2013-01-05  0.096433       NaN  1.658917
2013-01-06  1.274731  1.909123 -0.289111

In [14]: df.iloc[0:6].dropna()
Out[14]: 
                   A         B         C
2013-01-01  0.442692 -0.109415 -0.038182
2013-01-02  1.217950  0.006681 -0.067752
2013-01-04 -0.655948  0.484234  1.313306
2013-01-06  1.274731  1.909123 -0.289111

【讨论】:

不,实际上这不是我想要的。在您的示例中,需要 2013-01-03 行的 B 列和 C 列。只有那些具有 Nan 值的列不应被考虑。但非常感谢您提出建议。 如果您只想考虑列的子集,请尝试dropna(subset=['C'])【参考方案3】:

使用 Jeff 的数据框:

import pandas as pd
from numpy.random import randn

df = pd.DataFrame(randn(10,3),columns=list('ABC'),index=pd.date_range('20130101',periods=10))
df.ix[6,'A'] = np.nan
df.ix[6,'B'] = np.nan
df.ix[2,'A'] = np.nan
df.ix[4,'B'] = np.nan

我们可以用一些我们知道不在数据框中的数字来替换 nans:

df = df.fillna(999)

如果您只想保留非空值而不进行迭代,您可以这样做:

df_nona = df.apply(lambda x: list(filter(lambda y: y != 999, x)))
df_na = df.apply(lambda x: list(filter(lambda y: y == 999, x)))

这种方法的问题是结果是列表,因此您会丢失有关索引的信息。

df_nona
A    [-1.9804955861, 0.146116306853, 0.359075672435...
B    [-1.01963803293, -0.829747654648, 0.6950551455...
C    [2.40122968044, 0.79395493777, 0.484201174184,...
dtype: object

另一种选择是:

df1 = df.dropna()
index_na  = df.index ^ df1.index
df_na = df[index_na]

在这种情况下,您不会丢失有关索引的信息,尽管这与以前的答案非常相似。

希望对你有帮助!

【讨论】:

以上是关于从 pandas 数据框中的多行中提取非 nan 值的主要内容,如果未能解决你的问题,请参考以下文章

比较 pandas/numpy 中的 NaN 列

计算 Pandas 数据框中 np.nan 的数量

如何根据 pandas 数据框中的数据类型填充 NaN 值?

用 pandas 中的 empty_rows 替换 pandas 数据框中的 NaN [重复]

如何从python中的pandas数据框中的列中提取关键字(字符串)

从数据框中删除不包括一组列的列中的nan行。