当条件为真时,Pandas将数据帧分成多个

问题描述 投票:5回答:3

我有一个数据框,如下面的df。我想为条件为真的每个数据块创建一个新的数据帧,这样它就会返回df_1,df_2 .... df_n。

|      df           |       |  df_1 |   | df_2  |
| Value | Condition |       | Value |   | Value |
|-------|-----------|       |-------|---|-------|
| 2     | True      |   |   | 2     |   | 0     |
| 5     | True      |   |   | 5     |   | 5     |
| 4     | True      |   |   | 4     |   |       |
| 4     | False     |   |   |       |   |       |
| 2     | False     |   |   |       |   |       |
| 0     | True      |   |   |       |   |       |
| 5     | True      |   |   |       |   |       |
| 7     | False     |   |   |       |   |       |
| 8     | False     |   |   |       |   |       |      
| 9     | False     |   |   |       |   |       |

我唯一的想法是遍历数据帧,返回每个True值块的开始和结束索引,然后创建新的数据帧,循环遍历返回的索引,为每个开始/结束对返回类似的内容:

newdf = df.iloc[start:end]

但这样做似乎效率低下。

python python-3.x pandas split
3个回答
3
投票

这是一种替代解决方案。请注意consecutive_groups食谱来自more_itertools库。

from itertools import groupby
from operator import itemgetter

def consecutive_groups(iterable, ordering=lambda x: x):
    for k, g in groupby(enumerate(iterable), key=lambda x: x[0] - ordering(x[1])):
        yield map(itemgetter(1), g)

grps = consecutive_groups(df[df.Condition].index)

dfs = {i: df.iloc[list(j)] for i, j in enumerate(grps, 1)}

# {1:    Value Condition
# 0      2      True
# 1      5      True
# 2      4      True,
# 2:    Value Condition
# 5      0      True
# 6      5      True}

4
投票

创建由DataFrame创建的字典Seriescumsum创建的倒置布尔列,并为NaN添加没有组的wheres:

g = (~df['Condition']).cumsum().where(df['Condition'])
print (g)
0    0.0
1    0.0
2    0.0
3    NaN
4    NaN
5    2.0
6    2.0
7    NaN
8    NaN
9    NaN
Name: Condition, dtype: float64

#enumerate for starting groups from 1, 2, N
dfs = {i+1:v for i, (k, v) in enumerate(df[['Value']].groupby(g))}
print (dfs)
{1:    Value
0      2
1      5
2      4, 2:    Value
5      0
6      5}

print (dfs[1])
   Value
0      2
1      5
2      4

print (dfs[2])
   Value
5      0
6      5

2
投票

我决定提供一个答案,将每个'Value'放入自己的专栏中。

m = df.Condition.values
g = (~m).cumsum()
d = df.loc[m, 'Value']
g = g[m]
c = d.groupby(g).cumcount()
d.set_axis([c, g], inplace=False).unstack()

     0    2
0  2.0  0.0
1  5.0  5.0
2  4.0  NaN
© www.soinside.com 2019 - 2024. All rights reserved.