2015-10-22 7 views
5

私は3つの列、count_id、AMVと時間を含むcsvを持っています。パンダのデータフレーム - ラムダ計算とシリーズあたりの最小値

私はパンダを使用しており、これをデータフレームとして読み込んでいます。

results= pd.read_csv('./output.csv') 

まず、データフレームを最初にcount_id、次にAMVにソートします。

results_sorted = results.sort_index(by=['count_id','AMV'], ascending=[True, True]) 

これは、私は今、私は最終的に同じプロット上にプロットできるように、データ上でいくつかの正規化を実行したい

count_id AMV Hour 
0 16012E 4004 14 
1 16012E 4026 12 
2 16012E 4099 15 
3 16012E 4167 11 
4 16012E 4239 10 
5 16012E 4324 13 
6 16012E 4941 16 
7 16012E 5088 17 
8 16012E 5283  9 
9 16012E 5620  8 
10 16012E 5946 18 
11 16012E 6146  7 
12 16012W 3622 10 
13 16012W 3904 12 
14 16012W 3979 11 
15 16012W 4076  9 
16 16012W 4189 13 
17 16012W 4870 14 
18 16012W 4899 18 
19 16012W 5107 15 
20 16012W 5659  8 
21 16012W 6325  7 
22 16012W 6460 17 
23 16012W 6500 16 

を与えます。私がしたいのは、系列当たりのAMVの最小値(count_id)を見つけて、与えられたAMVからこの最小値を減算することです。これは私に新しい列AMV_normを与えます。以下のようになります

count_id AMV Hour AMV_norm 
0 16012E 4004 14   0 
1 16012E 4026 12  22 
2 16012E 4099 15  95 
3 16012E 4167 11  163 
4 16012E 4239 10  235 
5 16012E 4324 13  320 
6 16012E 4941 16  937 
7 16012E 5088 17  1084 
8 16012E 5283  9  1279 
9 16012E 5620  8  1616 
10 16012E 5946 18  1942 
11 16012E 6146  7  2142 
12 16012W 3622 10   0 
13 16012W 3904 12  282 
14 16012W 3979 11  357 
15 16012W 4076  9  454 
16 16012W 4189 13  567 
17 16012W 4870 14  1248 
18 16012W 4899 18  1277 
19 16012W 5107 15  1485 
20 16012W 5659  8  2037 
21 16012W 6325  7  2703 
22 16012W 6460 17  2838 
23 16012W 6500 16  2878 

にはどうすれば最小AMVシリーズごとの値ではなくAMVの全体的なの最小値を見つける関数を定義していますか?

def minimum_series_value(AMV): 
    return AMV.argmin() 

次に、新しい列を作成し、その行にデータを挿入する必要があります。

results_sorted['AMV_norm'] = results_sorted.apply(lambda row:results_sorted(row['AMV'])) 

答えて

3

は、変換分からAMV列を引き:

In [11]: df.groupby('count_id')["AMV"].transform('min') 
Out[11]: 
0  4004 
1  4004 
2  4004 
3  4004 
4  4004 
... 
21 3622 
22 3622 
23 3622 
dtype: int64 

In [12]: df["AMV"] - df.groupby('count_id')["AMV"].transform('min') 
Out[12]: 
0  0 
1  22 
2  95 
3  163 
4  235 
... 
21 2703 
22 2838 
23 2878 
dtype: int64 

In [13]: df["AMV_norm"] = df["AMV"] - df.groupby('count_id')["AMV"].transform('min') 
+0

ありがとう;)非常にクリアでシンプル – LearningSlowly

1

私はあなたがcount_idにグループ化したいと考えている、その後、現在の値とそのグループの最小値の差を計算します。私はそれは次のようになります知っています。

df['AMV_norm'] = (df.groupby('count_id').AMV 
        .transform(lambda group_series: group_series - np.min(group_series))) 

>>> df 
    count_id AMV Hour AMV_norm 
0 16012E 4004 14   0 
1 16012E 4026 12  22 
2 16012E 4099 15  95 
3 16012E 4167 11  163 
4 16012E 4239 10  235 
5 16012E 4324 13  320 
6 16012E 4941 16  937 
7 16012E 5088 17  1084 
8 16012E 5283  9  1279 
9 16012E 5620  8  1616 
10 16012E 5946 18  1942 
11 16012E 6146  7  2142 
12 16012W 3622 10   0 
13 16012W 3904 12  282 
14 16012W 3979 11  357 
15 16012W 4076  9  454 
16 16012W 4189 13  567 
17 16012W 4870 14  1248 
18 16012W 4899 18  1277 
19 16012W 5107 15  1485 
20 16012W 5659  8  2037 
21 16012W 6325  7  2703 
22 16012W 6460 17  2838 
23 16012W 6500 16  2878 

EDIT: @AndyHaydenによってアプローチが若干速いです:

%timeit df["AMV"] - df.groupby('count_id')["AMV"].transform('min') 
1000 loops, best of 3: 736 µs per loop 

%timeit df.groupby('count_id').AMV.transform(lambda x: x - np.min(x)) 
1000 loops, best of 3: 804 µs per loop 

%timeit df.groupby('count_id').AMV.apply(lambda x: x - np.min(x)) 
1000 loops, best of 3: 1.32 ms per loop 
+1

ラムダを使用する奇妙なよう変換でSeriesを返します! (applyを使用するのではなく) –

+0

私は同じパスを使用していると思いますが、* tranformは通常、ある値がグループに広がっていることを意味します(transform( 'min')など)。しかし、私は分かりません、それは私の理解でした。 –

+0

面白い、ありがとう。私はラムダを使うのがより快適ですが、アンディの反応はより速いと言います。努力をいただきありがとうございます! – LearningSlowly

関連する問題