Python 合并数据帧中的行
我有一个熊猫数据框,看起来像这样:Python 合并数据帧中的行,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个熊猫数据框,看起来像这样: df =pd.DataFrame([[0,10,0,'A','A',6,7],[11,21,1,'A','A',8,9],[0,13,1,'B','B',11,13],[0,12,1,'C','C',14,15],[13,14,0,'C','C',16,18]],columns=['Start Sample','End Sample','Value','Start Name','End Name','Start Time','End Time']) df O
df =pd.DataFrame([[0,10,0,'A','A',6,7],[11,21,1,'A','A',8,9],[0,13,1,'B','B',11,13],[0,12,1,'C','C',14,15],[13,14,0,'C','C',16,18]],columns=['Start Sample','End Sample','Value','Start Name','End Name','Start Time','End Time'])
df
Out[18]:
Start Sample End Sample Value Start Name End Name Start Time End Time
0 0 10 0 A A 6 7
1 11 21 1 A A 8 9
2 0 13 1 B B 11 13
3 0 12 1 C C 14 15
4 13 14 0 C C 16 18
如果行I+1
的开始时间和行I
的结束时间之间的差异是<3
例如,行1、2、3是具有相同值的连续行
df['Start Time'].iloc[2] - df['End Time'].iloc[1] is = 2
df['Start Time'].iloc[3] - df['End Time'].iloc[2] is = 1
因此,它们都应该合并。
我希望这些行变成:
df2
Out[25]:
Start Sample End Sample Value Start Name End Name Start Time End Time
0 0 10 0 A A 6 7
1 11 12 1 A C 8 15
2 13 14 0 C C 16 18
请注意,新合并行应具有:
1) Start Sample = to the Start Sample of the first row merged
2) End Sample = to the End Sample of the last row merged
3) Value = to the common value
4) Start Name = to the Start Name of the first row merged
5) End Name = to the End Name of the last row merged
6) Start Time = to the Start Name of the first row merged
7) End Name = to the End Name of the last row merged
可能有更好的方法可以做到这一点,但下面是
iterrows()
方法:
df =pd.DataFrame([[0,10,0,'A','A',6,7],[11,21,1,'A','A',8,9],[0,13,1,'B','B',11,13],[0,12,1,'C','C',14,15],[13,14,0,'C','C',16,18]],columns=['Start Sample','End Sample','Value','Start Name','End Name','Start Time','End Time'])
df['keep'] = ''
active_row = None
for i, row in df.iterrows():
if active_row is None:
active_row = i
df.loc[i,'keep'] = 1
continue
if row['Value'] != df.loc[active_row,'Value']:
active_row = i
df.loc[i,'keep'] = 1
continue
elif row['Start Time'] - df.loc[active_row,'End Time'] >= 3:
active_row = i
df.loc[i,'keep'] = 1
continue
df.loc[active_row,'End Time'] = row['End Time']
df.loc[active_row,'End Sample'] = row['End Sample']
df.loc[active_row,'End Name'] = row['End Name']
df.loc[i,'keep'] = 0
final_df=df[df.keep == 1].drop('keep',axis=1)
它遍历行,记住最后一行,并在循环过程中更新它。每个循环将一个行分类为保持(1)或不保留(0),并且我们使用它来手动地将它们过滤掉。 < P>首先,一些代码供您考虑,然后进行一些解释。这里的方法是根据您的“值”划分子集,并处理这些子数据帧
def agg(series):
if series.name.startswith('Start'):
return series.iloc[0]
return series.iloc[-1]
subsets = [subset.apply(agg) for _, subset in
df.groupby((df['Value']!=df['Value'].shift(1)).cumsum())]
pd.concat(subsets, axis=1).T
“棘手”的部分是df['Value']=df['Value'].shift(1)).cumsum()
。当“值”发生更改时,会找到该值。我们将按此分组,但首先cumsum()
给出唯一的值
在groupby
之后,您将遍历感兴趣的数据帧子集。从这里你可以做很多事情,这就是为什么这是灵活的
对于每个子集,apply
功能将应用于每个系列(列)。在您的例子中,您正在根据列名查找两个值中的一个,这样就可以对每个系列应用一个函数(agg
)
编辑:上述变更测试仅包括指定的两个标准之一。将两者都包括在内是很容易的,但是扩展了逻辑,所以应该稍微加以突破。对于这种逻辑,我已经超出了一条不合理的单行线的界限。因此groupby条件应该是:
val_chg = df['Value'] != df['Value'].shift(1)
time_chg = df['Start Time']-df['End Time'].shift(1) >=3
df.groupby((val_chg | time_chg).cumsum())
嗨,谢谢你的回答。但我只想在行I+1的开始时间和行I的结束时间之间的差值小于3时对行进行分组。。在哪里可以添加此条件?@gabboshow oops。用该逻辑附加编辑。混合并匹配任何布尔值以找到变化,然后按总和分组。