循环遍历groupby并添加新列

时间:2015-07-03 13:22:59

标签: python pandas

我需要编写一个小脚本来获取一些数据(大约50k行/文件),我的原始文件如下所示:

    Label   ID  TRACK_ID    QUALITY POSITION_X  POSITION_Y  POSITION_Z  POSITION_T  FRAME   RADIUS  VISIBILITY  MANUAL_COLOR    MEAN_INTENSITY  MEDIAN_INTENSITY    MIN_INTENSITY   MAX_INTENSITY   TOTAL_INTENSITY STANDARD_DEVIATION  ESTIMATED_DIAMETER  CONTRAST    SNR
    ID1119  1119    9       6.672     384.195     122.923   0   0   0   5   1   -10921639   81.495  0   0   255 7905    119.529 5.201   1   0.682
    ID2237  2237    9       7.078     381.019     122.019   0   1   1   5   1   -10921639   89.381  0   0   255 8670    122.301 5.357   1   0.731
    ID2512  2512    9       7.193     377.739     120.125   0   2   2   5   1   -10921639   92.01   0   0   255 8925    123.097 5.356   1   0.747
    (...)
    ID1102  1102    18      4.991     808.857     59.966    0   0   0   5   1   -10921639   52.577  0   0   255 5100    103.7   4.798   1   0.507
    (...)

它是一个相当大的表,行数高达5万。现在并非所有数据对我来说都很重要,我主要需要Track_ID以及X和Y位置。 所以我使用excel文件创建一个数据框,只访问相应的列

IN   df = pd.read_excel('.../sample.xlsx', 'Sheet1',parse_cols="D, F,G")

这可以按预期工作。每个track_id基本上都是需要分析的一组数据。因此,直接的方法是通过track_id

对数据帧进行分组
IN Grouping = df.groupby("TRACK_ID")

也按预期工作。现在我需要获取每个组的第一个POSITION_X值,并从该组中的其他POSITION_X值中减去它们。 现在,我已经读过循环可能不是最好的方法,但我不知道怎么做。

for name, group in Grouping:
    first_X = group.iloc[0, 1]
    vect = group.iloc[1:,1] - first_X    

这会将值存储在vect中,如果我将其打印出来,则会给出正确的值。但是,我有一个问题,我不知道如何将它现在添加到新列。 也许有人可以引导我进入正确的方向。提前谢谢。

修改 这是由chappers建议的

def f(grouped):
    grouped.iloc[1:] = 0
    return grouped

grouped = df.groupby('TRACK_ID')
df['Calc'] = grouped['POSITION_X'].apply(lambda x: x - x.iloc[0]) grouped['POSITION_X'].apply(f)
for name, group in grouped:
    print name
    print group

Input:    
     TRACK_ID  POSITION_X  POSITION_Y
0          9     384.195     122.923
1          9     381.019     122.019
2          9     377.739     120.125
3          9     375.211     117.224
4          9     373.213     113.938
5          9     371.625     110.161
6          9     369.803     106.424
7          9     367.717     103.239
8         18     808.857      59.966
9         18     807.715      61.032
10        18     808.165      63.133
11        18     810.147      64.853
12        18     812.084      65.084
13        18     812.880      63.683
14        18     812.083      62.203
15        18     810.041      61.188
16        18     808.568      62.260

Output for group == 9
   TRACK_ID  POSITION_X  POSITION_Y     Calc
0         9     384.195     122.923  384.195
1         9     381.019     122.019   -3.176
2         9     377.739     120.125   -6.456
3         9     375.211     117.224   -8.984
4         9     373.213     113.938  -10.982
5         9     371.625     110.161  -12.570
6         9     369.803     106.424  -14.392
7         9     367.717     103.239  -16.478

因此预期输出将是每组的第一个钙值为0

1 个答案:

答案 0 :(得分:0)

这是接近它的一种方法,使用apply方法从所有其他obs中减去第一项。

df = DataFrame({'A' : ['foo', 'foo', 'foo', 'foo',
                           'bar', 'bar', 'bar', 'bar'],
                    'C' : [1,2,3,4,4,3,2,1]})

grouped = df.groupby('A')
df['C1'] = grouped['C'].apply(lambda x: x - x.iloc[0]) 

这将有输入:

     A  C
0  foo  1
1  foo  2
2  foo  3
3  foo  4
4  bar  4
5  bar  3
6  bar  2
7  bar  1

和输出

     A  C  C1
0  foo  1   0
1  foo  2   1
2  foo  3   2
3  foo  4   3
4  bar  4   0
5  bar  3  -1
6  bar  2  -2
7  bar  1  -3