2016-09-20 61 views
1

我知道問題名稱有點模糊。根據不同列值分配唯一值

我的目標是根據我的數據框中的2列+唯一值分配全局鍵列。

例如

CountryCode | Accident 
    AFG   Car 
    AFG   Bike 
    AFG   Car 
    AFG   Plane 
    USA   Car 
    USA   Bike 
    UK   Car 

讓車= 01,自行車= 02,平面= 03

我的願望全局密鑰格式爲[意外] [COUNTRYCODE] [UniqueValue]

獨特價值是一個類似的[計數] [國家代碼]

因此,如果事故=汽車和國家代碼= AFG,並且它是第一次出現,全局密鑰將是01AFG01

所需的數據幀是這樣的:

CountryCode | Accident | GlobalKey 
    AFG   Car  01AFG01 
    AFG   Bike  02AFG01 
    AFG   Car  01AFG02 
    AFG   Plane  01AFG03 
    USA   Car  01USA01 
    USA   Bike  01USA02 
    UK   Car  01UK01 

我曾嘗試循環追加事故次數和COUNTRYCODE一起

例如運行:

globalKey = [] 

for x in range(0,6): 
    string = df.iloc[x, 1] 
    string2 = df.iloc[x, 2] 
    if string2 == 'Car': 
     number = '01' 
    elif string2 == 'Bike': 
     number = '02' 
    elif string2 == 'Plane': 
     number = '03' 
    #Concat the number of accident and Country Code 
    subKey = number + string 
    #Append to the list 
    globalKey.append(subKey) 

此代碼將根據我指定的值向我提供類似01AFG02AFG的東西。但我想通過計算CountryCodeAccident相似時的發生次數來指定唯一值。

我被困在上面的代碼。我認爲應該有更好的方式在熊貓中使用地圖功能。

感謝您的幫助! 非常感謝!

+2

不應該'AFG平面'行有'03AFG01'的'全局鍵'? –

+0

和'USA Bike'是'02USA01'? – danio

回答

5

您可以cumcount嘗試在若干步驟來實現這一點,就像這樣:

In [1]: df = pd.DataFrame({'Country':['AFG','AFG','AFG','AFG','USA','USA','UK'], 'Accident':['Car','Bike','Car','Plane','Car','Bike','Car']}) 

In [2]: df 
Out[2]: 
    Accident Country 
0  Car  AFG 
1  Bike  AFG 
2  Car  AFG 
3 Plane  AFG 
4  Car  USA 
5  Bike  USA 
6  Car  UK 

## Create a column to keep incremental values for `Country` 
In [3]: df['cumcount'] = df.groupby('Country').cumcount() 

In [4]: df 
Out[4]: 
    Accident Country cumcount 
0  Car  AFG   0 
1  Bike  AFG   1 
2  Car  AFG   2 
3 Plane  AFG   3 
4  Car  USA   0 
5  Bike  USA   1 
6  Car  UK   0 

## Create a column to keep incremental values for combination of `Country`,`Accident` 
In [5]: df['cumcount_type'] = df.groupby(['Country','Accident']).cumcount() 

In [6]: df 
Out[6]: 
    Accident Country cumcount cumcount_type 
0  Car  AFG   0    0 
1  Bike  AFG   1    0 
2  Car  AFG   2    1 
3 Plane  AFG   3    0 
4  Car  USA   0    0 
5  Bike  USA   1    0 
6  Car  UK   0    0 

而從這一點上,你可以連接的cumcountcumcount_typeCountry值達到你在做什麼後。

也許你想添加1在每次有值下的不同支數,這取決於你是否要開始計數爲0或1。

我希望這有助於。

+0

這不是OP所需要的,但也許他可以從中得到一個想法。 –

+0

你是對的@ Ev.Kounis,我會盡快澄清說明中的不一致之處。不過,我認爲這個問題從這一點變得微不足道,但一個確切的答案總是更好:) – Thanos

+0

我確實在這裏通過此代碼進行了擴展,並得到了一切工作。謝謝Thanos。 –

0

我沒有任何熊貓經驗,所以這個答案可能不是你要找的。這就是說,如果你擁有的數據真的很簡單(少數國家,幾乎沒有事故類型),你是否考慮過將每個國家的事故組合存儲起來?

因此,當您遍歷輸入時,只需遞增該國家/地區的事故組合的計數器,然後在末尾讀取這些計數器以生成GlobalKeys

如果除了全局密鑰之外您還有其他數據要存儲,那麼將國家|事故組合存儲爲列表,並在最後一次讀取它們以產生GlobalKeys

1

在您創建subKey之後,我們可以對數據框進行排序並計算對偶的出現次數。首先,讓我們重新索引由subKey排序(存儲原始順序)

df = df.reset_index() 

然後和計數

df = df.sort_values(by='subKey') 
df['newnumber'] = 1 

for ind in range(1, len(df)): #start by 1 because first row is always 1 
    if df.loc[ind, 'subKey'] == df.loc[ind - 1, 'subKey']: 
     df.loc[ind, 'newnumber'] = df.loc[ind - 1, 'newnumber'] + 1 

最後與zfill功能的幫助下,重新排序由index創建GlobalKey

df['GlobalKey'] = df.apply(lambda x: x['subKey'] + str(x['new_number']).zfill(2), 1) 
df = df.sort_values(by='index').drop('index', 1).reset_index(drop=True) 
1

首先,如果可以幫助它,請不要使用for循環。例如,你可以做你的意外與代碼映射:

df['AccidentCode'] = df['Accident'].map({'Car': '01', 'Bike': '02', 'Plane': '03'}) 

要獲得的唯一代碼,Thanos has shown how to do,使用GroupBy.cumcount

df['CA_ID'] = df.groupby(['CountryCode', 'Accident']).cumcount() + 1 

然後把它們一起放入唯一鍵:

df['NewKey'] = df['AccidentCode'] + df['CountryCode'] + df['CA_ID'].map('{:0>2}'.format) 

這給:

CountryCode Accident GlobalKey AccidentCode CA_ID NewKey 
0   AFG  Car 01AFG01   01  1 01AFG01 
1   AFG  Bike 02AFG01   02  1 02AFG01 
2   AFG  Car 01AFG02   01  2 01AFG02 
3   AFG Plane 01AFG03   03  1 03AFG01 
4   USA  Car 01USA01   01  1 01USA01 
5   USA  Bike 01USA02   02  1 02USA01 
6   UK  Car 01UK01   01  1 01UK01 
+0

這是一個非常短的版本,非常感謝你! –