循环前一行或下一行并进行计算 - Python

时间:2017-05-30 18:28:31

标签: python pandas

假设我有一个如下数据框,

ID  response    time
1   1315     1.434054
2   1682     3.753334
2   2829     5.940094
3   184      6.243214
4   243      6.301918
3   1413     7.486633
5   2400    11.474644
6   2151     3.288531

Dataframe有ID,响应和时间。

对于ID(1,4,5,6)中没有重复项的示例,我想返回时间。 对于ID(2,3)中有重复项的示例,我想在min_time列中返回两次的最小值,并在差异列中返回两次之间的差值。以下是我正在看的输出,

    ID       response    time      min_time     difference
     1         1315     1.434054    1.434054        NA
     2         1682     3.753334    3.753334      2.18676
     2         2829     5.940094    3.753334      2.18676
     3          184     6.243214    6.243214      1.243419
     4          243     6.301918    6.301918         NA
     3         1413     7.486633    6.243214      1.243419
     5         2400    11.474644    11.474644        NA
     6         2151     3.288531    3.288531         NA

虽然我能够使用循环来实现此输出,但它并不是最有效的方法,而且需要花费很多时间。有更好的方法吗?

3 个答案:

答案 0 :(得分:0)

这是一种丑陋的方式,涉及为每个ID构建一个最小时间字典。你没有提供这个问题的解决方案,所以我很难将它与你的工作进行比较,但这并不会太慢。

data = {}

with open(path) as File:
    for line in File:
        ID, response, time = line.split()
        if ID in data:
            data[ID].append([response, time])
        else:
            data.update({ID: [[response, time]]})

minTimes = {}
for ID, value in data.items():
    if len(value) > 1:
        for i, j in enumerate(value):
            if ID in minTimes:
                if value[i][1] < minTimes[ID]:
                    minTimes[ID] = value[i][1]
            else:
                minTimes[ID] = value[i][1]
    else:
        minTimes[ID] = 'NA'

for ID, value in data.items():
    for i, j in enumerate(value):
        if minTimes[ID] != 'NA':
            value[i] =  [
                            int(value[i][0]),
                            float(value[i][1]),
                            float(minTimes[ID]),
                            abs(float(value[i][1]) - float(minTimes[ID]))
                        ]
        else:
            value[i] =  [
                            int(value[i][0]),
                            float(value[i][1]),
                            float(value[i][1]),
                            minTimes[ID]
                        ]

print(data)

我会留给你格式化输出。当我使用它时,我只是使用了json.dumps来使其打印得很好,但是如果你想要它与你在问题中使用的格式相同,那么你必须自己做。

答案 1 :(得分:0)

你可以试试这个:

df['min_time'] = df.groupby('ID')['time'].transform(lambda x: x.min())

df['difference'] = df.groupby('ID')['time'].transform(lambda x: x.max()-x.min()).replace(0,np.nan)

print(df)

输出:

   ID  response       time   min_time  difference
0   1      1315   1.434054   1.434054         NaN
1   2      1682   3.753334   3.753334    2.186760
2   2      2829   5.940094   3.753334    2.186760
3   3       184   6.243214   6.243214    1.243419
4   4       243   6.301918   6.301918         NaN
5   3      1413   7.486633   6.243214    1.243419
6   5      2400  11.474644  11.474644         NaN
7   6      2151   3.288531   3.288531         NaN

答案 2 :(得分:0)

这是你需要的吗?除此之外,您还可以在transform

中尝试Pandas
funcs = dict(min_time  ='min', difference=np.ptp)
d1 = df.join(df.groupby(['ID']).time.agg(funcs), on=['ID'])
d1.loc[d1.difference==0]=np.nan

Out[27]: 
    ID  respon       time   min_time  difference
0  1.0  1315.0   1.434054   1.434054         NaN
1  2.0  1682.0   3.753334   3.753334    2.186760
2  2.0  2829.0   5.940094   3.753334    2.186760
3  3.0   184.0   6.243214   6.243214    1.243419
4  4.0   243.0   6.301918   6.301918         NaN
5  3.0  1413.0   7.486633   6.243214    1.243419
6  5.0  2400.0  11.474644  11.474644         NaN
7  6.0  2151.0   3.288531   3.288531         NaN