の一意の識別子を作成するための高速な方法私はデータを持っている目標は、そのそれぞれについて、特定の価格でID1のグループごとに一意のIDを取得することで、このPythonのパンダ:グループ
df
Out[10]:
ID1 ID2 Price Date
0 11 21 10.99 3/15/2016
1 11 22 11.99 3/15/2016
2 12 23 5 3/15/2016
3 11 21 10.99 3/16/2016
4 11 22 12.99 3/16/2016
5 11 21 10.99 3/17/2016
6 11 22 11.99 3/17/2016
ようになりますID2のように:
# Desired Result
df
Out[14]:
ID1 ID2 Price Date UID
0 11 21 10.99 3/15/2016 1
1 11 22 11.99 3/15/2016 1
2 12 23 5 3/15/2016 7
3 11 21 10.99 3/16/2016 5
4 11 22 12.99 3/16/2016 5
5 11 21 10.99 3/17/2016 1
6 11 22 11.99 3/17/2016 1
データのサイズのためにスピードが問題になります。私が思いつくことができる最善の方法は以下の通りですが、依然として望ましい量よりもゆっくりとかなりの量です。誰かが自然に速くなるべきと思う方法があれば、それを聞いてみたいです。あるいは、グループ内の操作を並行して実行する簡単な方法があります。
私の方法では、基本的にIDと価格を連結し(同じ長さを確保するために0で埋めた後に)、最後のIDを簡略化するためにランクをとります。ボトルネックは.transform(np.sum)で行われるグループ内連結です。
# concatenate ID2 and Price
df['ID23'] = df['ID2'] + df['Price']
df
Out[12]:
ID1 ID2 Price Date ID23
0 11 21 10.99 3/15/2016 2110.99
1 11 22 11.99 3/15/2016 2211.99
2 12 23 5 3/15/2016 235
3 11 21 10.99 3/16/2016 2110.99
4 11 22 12.99 3/16/2016 2212.99
5 11 21 10.99 3/17/2016 2110.99
6 11 22 11.99 3/17/2016 2211.99
# groupby ID1 and Date and then concatenate the ID23's
grouped = df.groupby(['ID1','Date'])
df['summed'] = grouped['ID23'].transform(np.sum)
df
Out[16]:
ID1 ID2 Price Date ID23 summed UID
0 6 3 0010.99 3/15/2016 30010.99 30010.9960011.99 630010.9960011.99
1 6 6 0011.99 3/15/2016 60011.99 30010.9960011.99 630010.9960011.99
2 7 7 0000005 3/15/2016 70000005 70000005 770000005
3 6 3 0010.99 3/16/2016 30010.99 30010.9960012.99 630010.9960012.99
4 6 6 0012.99 3/16/2016 60012.99 30010.9960012.99 630010.9960012.99
5 6 3 0010.99 3/17/2016 30010.99 30010.9960011.99 630010.9960011.99
6 6 6 0011.99 3/17/2016 60011.99 30010.9960011.99 630010.9960011.99
# Concatenate ID1 on the front and take rank to get simpler ID's
df['UID'] = df['ID1'] + df['summed']
df['UID'] = df['UID'].rank(method = 'min')
# Drop unnecessary columns
df.drop(['ID23','summed'], axis=1, inplace=True)
UPDATE:
明確にするために、次のようにグループ化された元のデータを検討します。そのグループについてのすべては日付を無視して、同一である場合
grouped = df.groupby(['ID1','Date'])
for name, group in grouped:
print group
ID1 ID2 Price Date
0 11 21 10.99 3/15/2016
1 11 22 11.99 3/15/2016
ID1 ID2 Price Date
3 11 21 10.99 3/16/2016
4 11 22 12.99 3/16/2016
ID1 ID2 Price Date
5 11 21 10.99 3/17/2016
6 11 22 11.99 3/17/2016
ID1 ID2 Price Date
2 12 23 5 3/15/2016
UIDのは、グループレベルと一致でなければなりません。この場合、最初と3番目の印刷グループは同じです。つまり、行0,1,5,6がすべて同じUIDを取得する必要があります。行3と4は異なるグループに属します。価格が変更され、異なるUIDが必要なためです。行2も異なるグループです。
この問題を見る方法が少し違うのは、私がここにあるようにグループ化したいのですが、最初にグループを作成するために重要だった日付列を削除してから、一度削除したグループ日付。
どのようにそれは ' 'UID''は'行でも同じです0'と '1'ということになりましたでしょうか?このような例'' ID1''は両方の行で同じですが、 '' ID2''と '' Price''は実際には異なっています。 – Thanos
良い質問です。私はもっと説明していたはずです。 ID1はID2の親IDと似ています。だから、行0と1は同じグループに属しています。そのグループのID1 = 11とその日のすべての子(ID2)です。そのグループレベルで一意のIDが必要です。 UIDは、ID1、ID2、および価格が同じであるため、異なる日であっても最後の2行と同じ行になります。 – Archimedes
__unique__識別子は任意の行を識別できる必要があります。そのため、列の名前を付けたり、行の一意性を保証したり、GUIDなどの人工的な固有キーを使用することができます。それ以外の場合は、すぐに、または固有のキーアルゴリズムに問題が発生します。ちょうど私の0.02 $。 – MaxU