關於Pandas Dataframe Series map 用法的效能問題

環境
Python 3.10.4
pandas 1.4.3

我有兩個Dataframe一個df_Dajia 一個df_offical
df_Dajia其中一個欄位會去跟df_offical的其中一個欄位比對資料是否有在裡面
有的話就在df_Dajia的座標欄位新增一筆資料 否則無
不過前面執行表達式的一些計算等多不到20秒


但是光上面這個程式就跑了將近七分鐘
如果是我的寫法有問題 那有改進的方法嗎
或是說有優化的方式

謝謝!

讨论数量: 9
Jason990420

Not sure if it work for you

import time
import pandas as pd

data1 = [[i, f'data {i}'] for i in range(3, 99999)]
data2 = [[i, 'None'] for i in range(100001)]
df_offical  = pd.DataFrame(data1, columns=['地址', 'TWD97橫座標'])
df_Dajia    = pd.DataFrame(data2, columns=['地址', 'TWD97橫座標'])

now = time.time()

df_Dajia.set_index('地址', inplace=True)
df_Dajia.update(df_offical.set_index('地址'))
df_Dajia.reset_index()

print(f'time passed: {int(time.time() - now)} seconds\n')
print(df_Dajia)
time passed: 0 seconds

          TWD97橫座標
地址                
0             None
1             None
2             None
3           data 3
4           data 4
...            ...
99996   data 99996
99997   data 99997
99998   data 99998
99999         None
100000        None

[100001 rows x 1 columns]
1年前 评论
RDan (楼主) 1年前
Jason990420

有些地址欄位會有重複

會出錯 …

>>> df_Dajia
   地址 TWD97橫座標
0   0     None
1   1     None
2   2     None
3   3     None
4   4     None
5   5     None
6   6     None
7   7     None
8   8     None
9   9     None
>>> df_offical
   地址 TWD97橫座標
0   3   data 3
1   4   data 4     # 地址欄位重複
2   4   data 5     # 地址欄位重複
Traceback (most recent call last):
  File "D:\test4.py", line 18, in <module>
    df.Dajia['TWD97橫座標'] = df_Dajia['地址'].map(match_row)
  File "C:\Software\Python\lib\site-packages\pandas\core\series.py", line 4237, in map
    new_values = self._map_values(arg, na_action=na_action)
  File "C:\Software\Python\lib\site-packages\pandas\core\base.py", line 880, in _map_values
    new_values = map_f(values, mapper)
  File "pandas\_libs\lib.pyx", line 2870, in pandas._libs.lib.map_infer
  File "D:\test4.py", line 16, in match_row
    return find_val.values.item()
ValueError: can only convert an array of size 1 to a Python scalar
>>> find_val = pd.Series(data=["data 4", "data 5"], name='TWD97橫座標')
>>> find_val.values.item()
Traceback (most recent call last):  
  File "<interactive input>", line 1, in <module>
ValueError: can only convert an array of size 1 to a Python scalar

座標欄位新增一筆資料

如何新增一筆 ? 字符串方式 “第一筆 第二筆” OK, 列表方式 [“第一筆”, “第二筆”] 會出錯.

1年前 评论
RDan (楼主) 1年前
Jason990420 (作者) 1年前
RDan (楼主) 1年前
def Match_column(value):
    #第一次比對 如果空的話
    if df_offical[df_offical['地址'].isin([value])].index.empty:
    #第二次比對因為前面空值  所以目前嘗試取得號前面的自 不包含樓
        value = re.findall(".*號",value)
        if df_offical[ df_offical['地址'].isin([value])].index.empty :
            return "無"
        else:
            print(df_offical[ df_offical['地址'].isin(value)]['TWD97橫坐標'].values.item())
            return df_offical[df_offical['地址'].isin(value)]['TWD97縱坐標'].values.item()
    else:
        return df_offical[df_offical['地址'].isin([value])]['TWD97縱坐標'].values.item()
df_Dajia['TWD97縱坐標'] = df_Dajia['地址'].apply(Match_column) 

想跟您請教一下 這是我自己寫的程式碼
不知道為什麼
假設
二段3號在df_offical裡面有資料
df_dajia裡面有幾筆
二段3號 有經緯度回傳
二段3號1樓 無
二段3號2樓 無
我的寫法是如果第一次把二段3號1樓丟到df_offical沒有回傳值
那我就把二段3號1樓用re.findall替換成二段3號
就我理解來說二段3號有在df_offical裡面 而且前一筆也有回傳值
不知道為什麼後面幾筆收不到回傳值

謝謝

1年前 评论
Jason990420

最好有可以執行的代碼來示範你的問題 !!!

df_offical[df_offical['地址'].isin([value])]

没有細看代碼, 但這個的用法有問題, 並非找符合的子字符串, 而是找符合列表['二段 3 號']中的元素 , 所以 '二段 3 號 x 樓' 都不符合.

1年前 评论
RDan (楼主) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!