【问题标题】:How to get the first index of a pandas DataFrame for which several undefined columns are not null?如何获取几个未定义列不为空的pandas DataFrame的第一个索引?
【发布时间】:2017-04-20 12:59:07
【问题描述】:

我有一个包含几列的数据框。我想获取第一行索引:

  • A 列的值不为空
  • 至少存在 n 个其他列的值不为空

示例:如果我的数据框是:

          Date          A             B      C     D
0   2015-01-02          NaN           1      1    NaN
1   2015-01-02          NaN           2      2    NaN
2   2015-01-02          NaN           3      3    NaN
3   2015-01-02          1            NaN     4    NaN
5   2015-01-02          NaN           2      NaN  NaN
6   2015-01-03          1            NaN     6    NaN
7   2015-01-03          1             1      6    NaN
8   2015-01-03          1             1      6     8

如果 n=1,我会得到 3

如果 n=2,我会得到 7

如果 n=3 我会得到 8

【问题讨论】:

  • 为什么 n=1,你会得到 6 而不是 3?
  • 过失,你是对的,已编辑。

标签: python pandas numpy dataframe multiple-columns


【解决方案1】:

这是一种一次性获取不同n's 的索引的方法 -

def numpy_approach(df, reference='A'):
    df0 = df.iloc[:,df.columns != 'Date']
    valid_mask = df0.columns != reference
    mask = ~np.isnan(df0.values)
    count = mask[:,valid_mask].sum(1) * mask[:,(~valid_mask).argmax()]
    idx0 = np.searchsorted(np.maximum.accumulate(count),[1,2,3])
    return df.index[idx0]

示例运行 -

In [555]: df
Out[555]: 
         Date    A    B    C    D
0  2015-01-02  NaN  1.0  1.0  NaN
1  2015-01-02  NaN  2.0  2.0  NaN
2  2015-01-02  NaN  3.0  3.0  NaN
3  2015-01-02  1.0  NaN  4.0  NaN
5  2015-01-02  NaN  2.0  NaN  NaN
6  2015-01-03  1.0  NaN  6.0  NaN
7  2015-01-03  1.0  1.0  6.0  NaN
8  2015-01-03  1.0  1.0  6.0  8.0

In [556]: numpy_approach(df, reference='A')
Out[556]: Int64Index([3, 7, 8], dtype='int64')

In [557]: numpy_approach(df, reference='B')
Out[557]: Int64Index([0, 7, 8], dtype='int64')

In [558]: numpy_approach(df, reference='C')
Out[558]: Int64Index([0, 7, 8], dtype='int64')

In [568]: numpy_approach(df, reference='D')
Out[568]: Int64Index([8, 8, 8], dtype='int64')

【讨论】:

  • 运行时出现以下错误:result = getitem(key) IndexError: index 50 is out of bounds for axis 1 with size 50
  • @Arty 有没有一种情况,我们没有 3 个不全为空的列?只是在代码中编辑了一些东西。您能否使用它运行并告诉我您可能在哪一行遇到该错误?
  • 是的,我没有确切地说明这个情况。我也没有明确目标列不是 A 而是 B 的情况,例如,在最后一种情况下怎么办?
  • @Arty 如果我理解您的评论,您想使用B 列作为参考,然后使用所有其他列吗?如果是这样,请编辑:colA_idx = np.argmax(df.columns == 'B'),即获取B 的列 ID,然后使用相同的代码。
  • 不,我的意思是使用 B 列作为参考,以及 B 列之前和之后的所有其他列。
【解决方案2】:

您可以先通过A 选择而不是NaN 并按loc 计数列,然后在notnull 的每行中获取sum,并为列1 减去1

最后使用布尔掩码 idxmax:

a = df.loc[df['A'].notnull(), 'A':].notnull().sum(axis=1).sub(1)
print (a)
3    1
6    1
7    2
8    3
dtype: int64

N = 1
print ((a == N).idxmax())
3

N = 2
print ((a == N).idxmax())
7

N = 3
print ((a == N).idxmax())
8

print (df.loc[df['A'].notnull(), 'A':])
     A    B    C    D
3  1.0  NaN  4.0  NaN
6  1.0  NaN  6.0  NaN
7  1.0  1.0  6.0  NaN
8  1.0  1.0  6.0  8.0

【讨论】:

  • 您的答案仅在 A 列是第一列时才有效,但如果之前还有其他列怎么办?
  • 嗯,你计算从Adf结尾的列吗? (B,C,D, ... 列?)
  • 并且您的示例中的列 A 是第二个,print (df.loc[df['A'].notnull(), 'A':]) 不返回用于计数的列(也有列 A 始终具有非 NaN 值,所以 sub(1) 减去它)。
  • 我认为您误解了我的评论。我的意思是,如果目标列不再是 A 而是 B,例如,之前和之后有列,该怎么办?如果 A 列中没有 1 但有其他内容怎么办?
  • 它也很好用。 print (df.loc[df['B'].notnull(), 'B':]) 并获取从Bend 的所有列,如果还需要从开始和结束的列,print (df[df['B'].notnull()])
猜你喜欢
  • 2020-07-26
  • 1970-01-01
  • 2023-03-02
  • 2021-02-03
  • 1970-01-01
  • 2017-09-02
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
相关资源
最近更新 更多