假设我们有以下dataframe
df = pd.DataFrame({'set_id': [0, 0,1,1,4,4,5,5,6,6],
'data': [-27, -45,-52,-65,-37, 20, 17, -45, -44, 15]})
set_id data
0 0 -27
1 0 -45
2 1 -52
3 1 -65
4 4 -37
5 4 20
6 5 17
7 5 -45
8 6 -44
9 6 15
我想在成对的后续集合之间执行一系列不同的计算,这意味着我需要以某种方式dataframe
“提取” set_id
(0,1),(4,5),(5,6),但不是(1,4)。
后续序列dataframe
set_id data
0 0 -27
1 0 -45
2 1 -52
3 1 -65
我用sequence_id
创建了另外一列,然后使用groupby.apply
,但是set_id
5是两个不同的序列,因此不是解决方案。
有解决方案吗?最好是一个熊猫人。
答案 0 :(得分:0)
如果将不成对的唯一值添加到上一个先前值,然后使用zip_longest
进行过滤,则可以使用带有fillvalue
参数的Series.isin
来生成组的值:
from itertools import zip_longest
a = df['set_id'].unique()
b = [(x, y) for x, y in zip_longest(a[::2], a[1::2], fillvalue=a[-2])]
print (b)
[(0, 1), (4, 5), (6, 5)]
for x in b:
df1 = df[df['set_id'].isin(x)]
print (df1)
set_id data
0 0 -27
1 0 -45
2 1 -52
3 1 -65
set_id data
4 4 -37
5 4 20
6 5 17
7 5 -45
set_id data
6 5 17
7 5 -45
8 6 -44
9 6 15
另一个想法是,如果取消配对唯一值,则添加最后一个上一组(此处为5):
df['g'] = pd.factorize(df['set_id'])[0] // 2
max_g = df.loc[df['g'] == df['g'].max(), 'set_id']
last_prev_df = df.loc[df['g'] == df['g'].max() - 1, 'set_id']
if max_g.nunique() == 1:
df1 = df[df['g'] != df['g'].max()]
df2 = df[df['set_id'] == last_prev_df.values[-1]].assign(g = df['g'].max())
df3 = df[df['g'] == df['g'].max()]
df = pd.concat([df1, df2, df3], ignore_index=False)
因此可以通过助手列g
进行分组,并应用自定义功能:
def func(x):
print (x)
df1 = df.groupby('g').apply(func)
set_id data g
0 0 -27 0
1 0 -45 0
2 1 -52 0
3 1 -65 0
set_id data g
4 4 -37 1
5 4 20 1
6 5 17 1
7 5 -45 1
set_id data g
6 5 17 2
7 5 -45 2
8 6 -44 2
9 6 15 2
答案 1 :(得分:0)
您可以获取符合您条件的数据框部分列表,如下所示:
json (~>1.8.3)
输出
import numpy as np
import pandas as pd
df = pd.DataFrame({'set_id': [0, 0,1,1,4,4,5,5,6,6],
'data': [-27, -45,-52,-65,-37, 20, 17, -45, -44, 15]})
id_sets = [(0,1), (4,5), (5,6)]
df_list = [df[np.in1d(df.set_id, id_set)] for id_set in id_sets]
for df in df_list:
display(df)
答案 2 :(得分:0)
如果要获取后续set_id值的索引对,则可以执行以下操作:
pairs = []
for r in df.itertuples():
if r.set_id and r.set_id == last.set_id+1:
pairs.append([last.Index, r.Index])
last = r
对然后包含索引对 [[1,2],[5,6],[7,8]]
的列表或者,要获取子数据帧:
pairs = [df.loc[x:x+1]
for x in range(0, df.shape[0]-1) if df.loc[x, 'set_id']==df.loc[x+1, 'set_id']-1]
对然后包含数据帧列表:
for s in pairs:
print(s, type(s))
Output:
set data
1 0 -45
2 1 -52 <class 'pandas.core.frame.DataFrame'>
set data
5 4 20
6 5 17 <class 'pandas.core.frame.DataFrame'>
set data
7 5 -45
8 6 -44 <class 'pandas.core.frame.DataFrame'>