我正在尋求有關以下問題的幫助。
我有一個資料框:
df = pd.DataFrame({
'ID1': ['blabla-012345-blabla', 'blabla-012345-blabla', 'blabla-012345-blabla', 'blabla-012345-blabla', 'blabla-1234567891-blabla', 'blabla-123456-blabla', 'blabla-0123456789-blabla', 'blabla-0123456789-blabla', 'blabla-0123456789-blabla'],
'ID2': ['blabla-012345-blabla', 'blabla-123456-blabla', 'blabla-0123456789-blabla', 'blabla-1234567891-blabla', 'blabla-012345-blabla', 'blabla-0123456789-blabla', 'blabla-123456-blabla', 'blabla-0123456789-blabla', 'blabla-1234567891-blabla'],
'ID3': ['1234512345', '12345123456', '12345123456789', '123451234567891', '123451234567891', '123456123456789', '123456123456789', '123456789123456789', '1234567891234567891'],
'case': ['10', '11', '14', '15a_1', '15a_2', '15b_1', '15b_2', '18', '19']
})
df
ID1 ID2 ID3 case
0 blabla-012345-blabla blabla-012345-blabla 1234512345 10
1 blabla-012345-blabla blabla-123456-blabla 12345123456 11
2 blabla-012345-blabla blabla-0123456789-blabla 12345123456789 14
3 blabla-012345-blabla blabla-1234567891-blabla 123451234567891 15a_1
4 blabla-1234567891-blabla blabla-012345-blabla 123451234567891 15a_2
5 blabla-123456-blabla blabla-0123456789-blabla 123456123456789 15b_1
6 blabla-0123456789-blabla blabla-123456-blabla 123456123456789 15b_2
7 blabla-0123456789-blabla blabla-0123456789-blabla 123456789123456789 18
8 blabla-0123456789-blabla blabla-1234567891-blabla 1234567891234567891 19
所有值都是字串,但我的資料在匯入到熊貓之前被認為是整數。
'blabla' 可以被認為是任何東西(不是隨機的,但知道解決這個問題是沒有用的),它們使從 ID1 和 ID2 重建 ID3 的方法復雜化。
這就是為什么我想從自身重建 ID3。
原本 ID3 應該是: 'ID3' = 'ID1number' 'ID2number' 如果 ID1number<ID2number 或 'ID3' = 'ID2number' 'ID1number' 如果 ID2number<ID1number。
但正如我所說的,ID 在匯入之前被認為是整數,所以在 ID1 和 ID2 中開始數字的“0”就消失了。
我想重建 ID3 以填充缺少的“0”。所以我做了這些掩碼來做到這一點,并嘗試更改與它們對應的值:
mask_ok = df['ID3'].str.contains('^(\d{12}|\d{16}|\d{20})$')
mask_10_18 = df['ID3'].str.contains('^(\d{10}|\d{18})$')
mask_11_19 = df['ID3'].str.contains('^(\d{11}|\d{19})$')
mask_14 = df['ID3'].str.contains('^\d{14}$')
mask_15a = ((df['ID3'].str.contains('^\d{15}$'))
&
(df['ID1'].str.startswith('^blabla-0\d{5}-')
|
df['ID2'].str.startswith('^blabla-0\d{5}-')))
mask_15b = ((df['ID3'].str.contains('^\d{15}$'))
&
~(df['ID1'].str.startswith('^blabla-0\d{5}-')
|
df['ID2'].str.startswith('^blabla-0\d{5}-')))
df.loc[mask_10_18] = '0' df.loc[mask_10_18][:len(df.loc[mask_10_18])/2] '0' df.loc[mask_10_18][len(df.loc[mask_10_18])/2:]
df.loc[mask_14] = '0' df.loc[mask_14][:5] '0' df.loc[mask_14][5:]
df.loc[mask_11_19|mask_15a] = '0' df.loc[mask_11_19|mask_15a]
df.loc[mask_15b] = df.loc[mask_15b][:6] '0' df.loc[mask_15b][6:]
df[~mask_ok]
我想要的是所有零都放置得很好,以便資料框看起來像這樣:
df = pd.DataFrame({
'ID1': ['blabla-012345-blabla', 'blabla-012345-blabla', 'blabla-012345-blabla', 'blabla-012345-blabla', 'blabla-1234567891-blabla', 'blabla-123456-blabla', 'blabla-0123456789-blabla', 'blabla-0123456789-blabla', 'blabla-0123456789-blabla'],
'ID2': ['blabla-012345-blabla', 'blabla-123456-blabla', 'blabla-0123456789-blabla', 'blabla-1234567891-blabla', 'blabla-012345-blabla', 'blabla-0123456789-blabla', 'blabla-123456-blabla', 'blabla-0123456789-blabla', 'blabla-1234567891-blabla'],
'ID3': ['012345012345', '012345123456', '0123450123456789', '0123451234567891', '0123451234567891', '1234560123456789', '1234560123456789', '01234567890123456789', '01234567891234567891'],
'case': ['12', '12', '16', '16', '16', '16', '16', '20', '20']
})
df
ID1 ID2 ID3 case
0 blabla-012345-blabla blabla-012345-blabla 012345012345 12
1 blabla-012345-blabla blabla-123456-blabla 012345123456 12
2 blabla-012345-blabla blabla-0123456789-blabla 0123450123456789 16
3 blabla-012345-blabla blabla-1234567891-blabla 0123451234567891 16
4 blabla-1234567891-blabla blabla-012345-blabla 0123451234567891 16
5 blabla-123456-blabla blabla-0123456789-blabla 1234560123456789 16
6 blabla-0123456789-blabla blabla-123456-blabla 1234560123456789 16
7 blabla-0123456789-blabla blabla-0123456789-blabla 01234567890123456789 20
8 blabla-0123456789-blabla blabla-1234567891-blabla 01234567891234567891 20
列案例只是在這里顯示 ID3 中的數字數量,但它不在我的原始資料框中,我只是把它放在那里以改善可視化。你可以去掉它進行計算。
運行代碼時出現此錯誤:
TypeError Traceback (most recent call last)
<ipython-input-30-91bff8470cf6> in <module>
19 df['ID2'].str.startswith('^blabla-0')))
20
---> 21 df.loc[mask_10_18] = '0' df.loc[mask_10_18][:len(df.loc[mask_10_18])/2] '0' df.loc[mask_10_18][len(df.loc[mask_10_18])/2:]
22
23 df.loc[mask_14] = '0' df.loc[mask_14][:5] '0' df.loc[mask_14][5:]
~\Anaconda3\lib\site-packages\pandas\core\frame.py in __getitem__(self, key)
2997
2998 # Do we have a slicer (on rows)?
-> 2999 indexer = convert_to_index_sliceable(self, key)
3000 if indexer is not None:
3001 if isinstance(indexer, np.ndarray):
~\Anaconda3\lib\site-packages\pandas\core\indexing.py in convert_to_index_sliceable(obj, key)
2208 idx = obj.index
2209 if isinstance(key, slice):
-> 2210 return idx._convert_slice_indexer(key, kind="getitem")
2211
2212 elif isinstance(key, str):
~\Anaconda3\lib\site-packages\pandas\core\indexes\base.py in _convert_slice_indexer(self, key, kind)
3355 if self.is_integer() or is_index_slice:
3356 self._validate_indexer("slice", key.start, "getitem")
-> 3357 self._validate_indexer("slice", key.stop, "getitem")
3358 self._validate_indexer("slice", key.step, "getitem")
3359 return key
~\Anaconda3\lib\site-packages\pandas\core\indexes\base.py in _validate_indexer(self, form, key, kind)
5307 pass
5308 else:
-> 5309 raise self._invalid_indexer(form, key)
5310
5311 def _maybe_cast_slice_bound(self, label, side: str_t, kind):
TypeError: cannot do slice indexing on Int64Index with these indexers [1.0] of type float
我認為這是因為 Pandas 正在將我的字串切片視為資料幀上的鏈接切片。
我還嘗試將 .str 放在所有對字串的呼叫之前(如掩碼中的 .str.contains),但它也不起作用。
我該怎么做呢?
uj5u.com熱心網友回復:
在我的問題中,我是說從 ID1 和 ID2 重建 ID3 會被 blabla- 和 -blabla 復雜化。這是錯誤的,因為我可以從 ID1 和 ID2 中提取數字(甚至是特定數量的數字)。
df = pd.DataFrame({
'ID1': ['blabla-012345-blabla', 'blabla-012345-blabla', 'blabla-012345-blabla', 'blabla-012345-blabla', 'blabla-1234567891-blabla', 'blabla-123456-blabla', 'blabla-0123456789-blabla', 'blabla-0123456789-blabla', 'blabla-0123456789-blabla'],
'ID2': ['blabla-012346-blabla', 'blabla-123456-blabla', 'blabla-0123456789-blabla', 'blabla-1234567891-blabla', 'blabla-012345-blabla', 'blabla-0123456789-blabla', 'blabla-123456-blabla', 'blabla-0123456799-blabla', 'blabla-1234567891-blabla'],
'ID3': ['1234512345', '12345123456', '12345123456789', '123451234567891', '123451234567891', '123456123456789', '123456123456789', '123456789123456789', '1234567891234567891'],
'case': ['10', '11', '14', '15a_1', '15a_2', '15b_1', '15b_2', '18', '19']
})
df['num_ID1'] = df['ID1'].str.extractall(r'(\d )').droplevel('match')
df['num_ID2'] = df['ID2'].str.extractall(r'(\d )').droplevel('match')
df.loc[df['num_ID1'].astype(int)<df['num_ID2'].astype(int), 'new_col'] = df['num_ID1'] df['num_ID2']
df.loc[df['num_ID2'].astype(int)<df['num_ID1'].astype(int), 'new_col'] = df['num_ID2'] df['num_ID1']
df
df1 = pd.DataFrame({
'ID1': ['blabla-012345-blabla', 'blabla-012345-blabla', 'blabla-012345-blabla', 'blabla-012345-blabla', 'blabla-1234567891-blabla', 'blabla-123456-blabla', 'blabla-0123456789-blabla', 'blabla-0123456789-blabla', 'blabla-0123456789-blabla'],
'ID2': ['blabla-012346-blabla', 'blabla-123456-blabla', 'blabla-0123456789-blabla', 'blabla-1234567891-blabla', 'blabla-012345-blabla', 'blabla-0123456789-blabla', 'blabla-123456-blabla', 'blabla-0123456799-blabla', 'blabla-1234567891-blabla'],
'ID3': ['012345012346', '012345123456', '0123450123456789', '0123451234567891', '0123451234567891', '1234560123456789', '1234560123456789', '01234567890123456799', '01234567891234567891'],
'case': ['10', '11', '14', '15a_1', '15a_2', '15b_1', '15b_2', '18', '19']
})
print(df1['ID3']==df['new_col'])
0 True
1 True
2 True
3 True
4 True
5 True
6 True
7 True
8 True
dtype: bool
實際上,它比嘗試屏蔽所有情況并根據條件對每個 ID3 進行切片要簡單。我現在應該注意 'blabla' 可能是隨機的,所以我只需要提取一定長度的組來做到這一點。它會完成。在這個例子中,使用字串提取比我簡單。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/393396.html
