在pandas中创建运行总计列的最佳方式是什么?



在不同级别(不遍历行)创建运行总数列的最随机的方法是什么?

输入:

import pandas as pd
import numpy as np
df = pd.DataFrame()
df['test'] = np.nan,np.nan,'X','X','X','X',np.nan,'X','X','X','X','X','X',np.nan,np.nan,'X','X'
df['desired_output_level_1'] = np.nan,np.nan,'1','1','1','1',np.nan,'2','2','2','2','2','2',np.nan,np.nan,'3','3'
df['desired_output_level_2'] = np.nan,np.nan,'1','2','3','4',np.nan,'1','2','3','4','5','6',np.nan,np.nan,'1','2'

输出:

test desired_output_level_1 desired_output_level_2
0   NaN                    NaN                    NaN
1   NaN                    NaN                    NaN
2     X                      1                      1
3     X                      1                      2
4     X                      1                      3
5     X                      1                      4
6   NaN                    NaN                    NaN
7     X                      2                      1
8     X                      2                      2
9     X                      2                      3
10    X                      2                      4
11    X                      2                      5
12    X                      2                      6
13  NaN                    NaN                    NaN
14  NaN                    NaN                    NaN
15    X                      3                      1
16    X                      3                      2

test列只能包含X或nan。连续X的个数是随机的。

在'desired_output_level_1'列中,尝试计算X系列的数量。

在'desired_output_level_2'列中,尝试查找每个系列的持续时间。

有人能帮忙吗?提前谢谢。

也许不是最神奇的方法,但似乎能得到你想要的。

三个要点:

  1. 我们只对非NaN行进行操作,所以让我们创建一个掩码:
mask = df['test'].notna()
  1. 对于一级计算,当从NaN到非NaN变化时,通过移动一行很容易进行比较:
df.loc[mask, "level_1"] = (df["test"].isna() & df["test"].shift(-1).notna()).cumsum()
  1. 对于二级计算,这有点棘手。一种方法是为每个level_1组运行计算,并执行.transform以保留索引:
df.loc[mask, "level_2"] = (
df.loc[mask, ["level_1"]]
.assign(level_2=1)
.groupby("level_1")["level_2"]
.transform("cumsum")
)

最后一步(如果需要)是将列转换为strings:

df['level_1'] = df['level_1'].astype('Int64').astype('str')
df['level_2'] = df['level_2'].astype('Int64').astype('str')

相关内容

  • 没有找到相关文章