我正在尝试从查看索引的df2数据帧(第一列或零列df2 [0])中找到具有开始值和结束值(即行)的元组列表。 df2例子:
COL0 COL1 COL2
4 x y # start 'tuple x' of COL1
5 i j
6 n m # end 'tuple n'
14 f a # start 'tuple f'
15 e b # end 'tuple e'
...
因此COL0连续值将形成一个组。如果下一行不连续(例如6-14),则开始新组。选择可能如下:
Crit_a = df2[0][0] + 1 == df2[0][1]
作为输出,我正在寻找每行新的df3:
COL0 COL1 COL2 COL3 COL4 ...
4 x y n m # start values and end values of COL1 and COL2
14 f a e b
我正在查看SO here和其他位置。 谢谢你的建议。
答案 0 :(得分:1)
首先为属于同一组的行创建一个组密钥。
df['COL0'] = \
(df.COL0.rolling(2,min_periods=1)
.apply(lambda x: x[-1] if int(x[-1]-x[0])!=1 else np.nan)
.ffill()
)
然后按键分组并找到开始和结束行并将它们展开为列。最后重命名列。
df2 = \
(df[['COL1','COL2']].groupby(df.COL0)
.apply(lambda x: np.array([x.iloc[0],x.iloc[-1]]).flatten())
.apply(pd.Series)
.rename_axis(lambda x: 'COL'+str(x+1),axis=1)
)
df2
Out[178]:
COL1 COL2 COL3 COL4
COL0
4.0 x y n m
14.0 f a e b
答案 1 :(得分:1)
不完全是您想要的输出,但可能更直观?
我创建了一个名为group_no
的列来标记来自COL0
的连续值。我区分了列,找到了这个差异不是1的值,然后在结果上做了一个cumsum。第一个元素是不明确的(当差异时它是NaN,所以我检查它的值是否等于第二个值。如果是这样,第一个值是连续的并且赋值为1.如果不是,则它不是连续的并且分配了一个值为0.
df = df.assign(group_no = (df.COL0.diff() != 1).cumsum())
df.group_no.iat[0] = 1 if df.COL0.iat[0] + 1 == df.COL0.iat[1] else 0
df_new = df.groupby('group_no').agg(
{'COL0': ['first'],
'COL1': ['first', 'last'],
'COL2': ['first', 'last']})
>>> df_new
COL2 COL0 COL1
first last first first last
group_no
1 y m 4 x n
2 a b 14 f e
agg
函数采用字典,因此列的结果顺序可以是任意的。要对结果列进行排序,您可以明确地执行此操作,例如:
df_new[[('COL0', 'first'),
('COL1', 'first'),
('COL1', 'last'),
('COL2', 'first'),
('COL2', 'last')]]
这也可能有效:
n = 3 # First three columns of original dataframe.
df_new.loc[:, pd.IndexSlice[df.columns[:n], :]]