获取行或列中非空值的快速方法

huangapple go评论69阅读模式
英文:

Fast way to get index of non-blank values in row/column

问题

让我们假设我们有以下的pandas数据框:

df = pd.DataFrame({'a': {0: 3.0, 1: 2.0, 2: None}, 'b': {0: 10.0, 1: None, 2: 8.0}, 'c': {0: 4.0, 1: 2.0, 2: 6.0}})

     a     b    c
0  3.0  10.0  4.0
1  2.0   NaN  2.0
2  NaN   8.0  6.0

我需要获得一个数据框,对于每一行,包含所有非NaN值的列名。
我知道我可以使用以下方法,产生预期的输出:

df2 = df.apply(lambda x: pd.Series(x.dropna().index), axis=1)

   0  1    2
0  a  b    c
1  a  c  NaN
2  b  c  NaN

不幸的是,对于大型数据集,这种方法速度较慢。是否有更快的方法?

获取每列的非Null值的行索引也可以工作,因为我只需转置输入数据框。谢谢。
英文:

Let's say we have the following pandas dataframe:

df = pd.DataFrame({'a': {0: 3.0, 1: 2.0, 2: None}, 'b': {0: 10.0, 1: None, 2: 8.0}, 'c': {0: 4.0, 1: 2.0, 2: 6.0}})

     a     b    c
0  3.0  10.0  4.0
1  2.0   NaN  2.0
2  NaN   8.0  6.0

I need to get a dataframe with, for each row, the column names of all non-NaN values.
I know I can do the following, which produces the expected outupt:

df2 = df.apply(lambda x: pd.Series(x.dropna().index), axis=1)

   0  1    2
0  a  b    c
1  a  c  NaN
2  b  c  NaN

Unfortunately, this is quite slow with large datasets. Is there a faster way?

Getting the row indices of non-Null values of each column could work too, as I would just need to transpose the input dataframe. Thanks.

答案1

得分: 3

使用 [tag:numpy]:
```python
m = df.notna()
a = m.mul(df.columns).where(m).to_numpy()
out = pd.DataFrame(a[np.arange(len(a))[:,None], np.argsort(~m, axis=1)],
                   index=df.index)

输出:

   0  1    2
0  a  b    c
1  a  c  NaN
2  b  c  NaN

时间统计

在 30k 行 x 3 列数据上:

# 使用 numpy 方法
6.82 毫秒 ± 1.56 毫秒 每次循环(均值 ± 7 次运行的标准差,100 次循环)

# 使用 pandas apply 方法
7.32 秒 ± 553 毫秒 每次循环(均值 ± 7 次运行的标准差,1 次循环)
英文:

Use [tag:numpy]:

m = df.notna()
a = m.mul(df.columns).where(m).to_numpy()
out = pd.DataFrame(a[np.arange(len(a))[:,None], np.argsort(~m, axis=1)],
                   index=df.index)

Output:

   0  1    2
0  a  b    c
1  a  c  NaN
2  b  c  NaN

timings

On 30k rows x 3 columns:

# numpy approach
6.82 ms ± 1.56 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

# pandas apply
7.32 s ± 553 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

huangapple
  • 本文由 发表于 2023年2月19日 01:28:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75495108.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定