pandas 扩展所有列的标准差

lzfw57am  于 2023-04-28  发布在  其他
关注(0)|答案(4)|浏览(159)

我有以下dataframe:

a  b  c
day         
1    2  2  8
2    1  2  2
3    7  2  3
4    2  9  7
5    4  6  4

我想得到一个新的列(“std”),它包含所有列值的扩展标准差。NaN应该被忽略。这是预期的输出:

a  b  c       std
day                   
1    2  2  8  2.828427
2    1  2  2  2.339278
3    7  2  3  2.346524
4    2  9  7  2.782635
5    4  6  4  2.542090

例如,2.339278等于numpy.std([2,2,8,1,2,2])
我尝试了以下方法:

df['std']  =  df.reset_index().groupby('day').expanding().std()

但导致以下TypeError:插入列与框架索引不相容索引
有人帮忙吗?谢谢

sdnqo3pr

sdnqo3pr1#

一种更快的方法,基于扁平数组的 * 扩展 *:

df['std'] = (pd.Series(df.values.ravel()).expanding(3)
             .std(ddof=0).dropna()[::3].values)
a  b  c       std
day                   
1    2  2  8  2.828427
2    1  2  2  2.339278
3    7  2  3  2.346524
4    2  9  7  2.782635
5    4  6  4  2.542090

执行时间比较:

In [223]: %timeit pd.Series(df.values.ravel()).expanding(3).std(ddof=0).dropna()[::3].values
242 µs ± 2.56 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [224]: %timeit df.stack().expanding().std(ddof=0).groupby(level=0).last()
664 µs ± 17 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [225]: %timeit df.apply(lambda x: np.std(df.loc[:x.name].values), axis=1)
617 µs ± 15.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [226]: %timeit df.stack().expanding().std(ddof=0)[:, 'c']
427 µs ± 1.78 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
pgky5nke

pgky5nke2#

一种方法是stack + expanding + std + index每三个值,但这意味着你也计算中间体的std:

df["std"] = df.stack().expanding().std(ddof=0)[:, 'c']

df

a  b  c       std
day
1    2  2  8  2.828427
2    1  2  2  2.339278
3    7  2  3  2.346524
4    2  9  7  2.782635
5    4  6  4  2.542090
wxclj1h5

wxclj1h53#

试试这个:

df = pd.DataFrame({'a': [2, 1, 7, 2, 4],
                   'b': [2, 2, 2, 9, 6],
                   'c': [8, 2, 3, 7, 4]},
                  index=[1, 2, 3, 4, 5])
df['std'] = df.apply(lambda x: np.std(df.loc[:x.name].values), axis=1)

输出:

a   b   c   std
1   2   2   8   2.828427
2   1   2   2   2.339278
3   7   2   3   2.346524
4   2   9   7   2.782635
5   4   6   4   2.542090
kzmpq1sx

kzmpq1sx4#

如果数据中有NaN,示例也应该这样。

示例

data = {'a': {1: 2, 2: 1, 3: 7, 4: 2, 5: 4},
 'b': {1: 2, 2: 2, 3: 2, 4: 9, 5: 6},
 'c': {1: 8.0, 2: 2.0, 3: None, 4: 7.0, 5: 4.0}}
df = pd.DataFrame(data).rename_axis('day')

df

a   b   c
day         
1   2   2   8.0
2   1   2   2.0
3   7   2   NaN
4   2   9   7.0
5   4   6   4.0

编码

df['std'] = df.stack().expanding().std(ddof=0).groupby(level=0).last()

df

a   b   c   std
day             
1   2   2   8.0 2.828427
2   1   2   2.0 2.339278
3   7   2   NaN 2.487469
4   2   9   7.0 2.891995
5   4   6   4.0 2.614715

相关问题