Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 合并数据帧中的行_Python_Pandas_Dataframe - Fatal编程技术网

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。用该逻辑附加编辑。混合并匹配任何布尔值以找到变化,然后按总和分组。