当发现NaN行时拆分数据框



当使用grps = dfs.isnull().all(axis=1).cumsum()发现NaN行时,我试图拆分数据帧。

但这不是工作时的一些行南入口在一列。

import pandas as pd
from pprint import pprint
import numpy as np
d = {
't': [0, 1, 2, 0, 2, 0, 1],
'input': [2, 2, 2, 2, 2, 2, 4],
'type': ['A', 'A', 'A', 'B', 'B', 'B', 'A'],
'value': [0.1, 0.2, 0.3, np.nan, 2, 3, 1],
}
df = pd.DataFrame(d)
dup = df['t'].diff().lt(0).cumsum()
dfs = (
df.groupby(dup, as_index=False, group_keys=False)
.apply(lambda x: pd.concat([x, pd.Series(index=x.columns, name='').to_frame().T]))
)
pprint(dfs)
grps = dfs.isnull().all(axis=1).cumsum()
temp = [dfs.dropna() for _, dfs in dfs.groupby(grps)]
i = 0
dfm = pd.DataFrame()
for df in temp:
df["name"] = f'name{i}'
i=i+1
df = df.append(pd.Series(dtype='object'), ignore_index=True)
dfm = dfm.append(df, ignore_index=True)
print(dfm)

输入df:

t  input type  value
0  0.0    2.0    A    0.1
1  1.0    2.0    A    0.2
2  2.0    2.0    A    0.3
NaN    NaN  NaN    NaN
3  0.0    2.0    B    NaN
4  2.0    2.0    B    2.0
NaN    NaN  NaN    NaN
5  0.0    2.0    B    3.0
6  1.0    4.0    A    1.0

输出获得:

t  input type  value   name
0  0.0    2.0    A    0.1  name0
1  1.0    2.0    A    0.2  name0
2  2.0    2.0    A    0.3  name0
3  NaN    NaN  NaN    NaN    NaN
4  2.0    2.0    B    2.0  name1
5  NaN    NaN  NaN    NaN    NaN
6  0.0    2.0    B    3.0  name2
7  1.0    4.0    A    1.0  name2
8  NaN    NaN  NaN    NaN    NaN
9  NaN    NaN  NaN    NaN    NaN
预期:

t  input type  value   name
0  0.0    2.0    A    0.1  name0
1  1.0    2.0    A    0.2  name0
2  2.0    2.0    A    0.3  name0
3  NaN    NaN  NaN    NaN    NaN
4  0.0    2.0    B    NaN  name1
5  2.0    2.0    B    2.0  name1
6  NaN    NaN  NaN    NaN    NaN
7  0.0    2.0    B    3.0  name2
8  1.0    4.0    A    1.0  name2
9  NaN    NaN  NaN    NaN    NaN

我基本上这样做是为了在分割df后将名称附加到数据框的最后一列使用

dfs = (
df.groupby(dup, as_index=False, group_keys=False)
.apply(lambda x: pd.concat([x, pd.Series(index=x.columns, name='').to_frame().T]))
)

和附加NaN行。

同样,我使用NaN行将df拆分为列表并添加新列。但是dfs.isnull().all(axis=1).cumsum()对我不起作用。我也得到了一个额外的NaN行在最后一行的输出。

关于如何获得预期输出的建议将非常有帮助。

设置

df = pd.DataFrame(d)
print(df)
t  input type  value
0  0      2    A    0.1
1  1      2    A    0.2
2  2      2    A    0.3
3  0      2    B    NaN
4  2      2    B    2.0
5  0      2    B    3.0
6  1      4    A    1.0

简化方法

# assign name column before splitting
m = df['t'].diff().lt(0)
df['name'] = 'name' + m.cumsum().astype(str)
# Create null dataframes to concat
nan_rows = pd.DataFrame(index=m[m].index) 
last_nan_row = pd.DataFrame(index=df.index[[-1]])
# Concat and sort index
df_out = pd.concat([nan_rows, df, last_nan_row]).sort_index(ignore_index=True)
结果

t  input type  value   name
0  0.0    2.0    A    0.1  name0
1  1.0    2.0    A    0.2  name0
2  2.0    2.0    A    0.3  name0
3  NaN    NaN  NaN    NaN    NaN
4  0.0    2.0    B    NaN  name1
5  2.0    2.0    B    2.0  name1
6  NaN    NaN  NaN    NaN    NaN
7  0.0    2.0    B    3.0  name2
8  1.0    4.0    A    1.0  name2
9  NaN    NaN  NaN    NaN    NaN

或者,如果您仍然希望以初始输入作为dfs开始,这里有另一种方法:

dfs = dfs.reset_index(drop=True)
m = dfs.isna().all(1)
dfs.loc[~m, 'name'] = 'name' + m.cumsum().astype(str)

最新更新