我有一个 pd 数据框:
import pandas as pd
column1 = [None,None,None,4,8,9,None,None,None,2,3,5,None]
column2 = [None,None,None,None,5,1,None,None,6,3,3,None,None]
column3 = [None,None,None,3,None,7,None,None,7,None,None,1,None]
df = pd.DataFrame(np.column_stack([column1, column2,column3]),columns=['column1', 'column2', 'column3'])
print(df)
column1 column2 column3
0 None None None
1 None None None
2 None None None
3 4 None 3
4 8 5 None
5 9 1 7
6 None None None
7 None None None
8 None 6 7
9 2 3 None
10 3 3 None
11 5 None 1
12 None None None
我想对第 3 列中的值之间的行进行子集化,并删除所有空行。我想要的结果是:
print (df1)
column1 column2 column3
0 4 None 3
1 8 5 None
2 9 1 7
print(df2)
column1 column2 column3
0 None 6 7
1 2 3 None
2 3 3 None
3 5 None 1
我不关心第3列的实际值。第 3 列值用于指示“开始”和“停止”。
您可以找到非 na 值,然后执行累加和,然后模 2 以获得起始位置和小于 1 停止位置的“组”。将其移动 1,添加到原始值,然后剪辑到 (0, 1) 得到起点和终点的团块。
要标记组,您可以将 diff 设为 1,然后再次剪辑到 (0, 1),求和,然后将这两者相乘。
g_small = (~df.column3.isna()).cumsum().mod(2)
g = (g_small + g_small .shift(1, fill_value=0)).clip(0,1)
groups = g.diff(1).fillna(0).clip(0,1).cumsum().astype(int) * g
然后您可以对数据框进行
groupby
操作:
dfs = {i: g for i, g in df.groupby(groups) if i > 0}
dfs
# returns:
{1:
column1 column2 column3
3 4 None 3
4 8 5 None
5 9 1 7,
2:
column1 column2 column3
8 None 6 7
9 2 3 None
10 3 3 None
11 5 None 1}