最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Pandas數(shù)據(jù)處理加速技巧匯總

 更新時間:2022年04月18日 14:02:02   作者:Mr數(shù)據(jù)楊  
Pandas?處理數(shù)據(jù)的效率還是很優(yōu)秀的,相對于大規(guī)模的數(shù)據(jù)集只要掌握好正確的方法,就能讓在數(shù)據(jù)處理時間上節(jié)省很多很多的時間。本文為大家匯總了一些Pandas數(shù)據(jù)處理加速技巧,需要的可以參考一下

Pandas 處理數(shù)據(jù)的效率還是很優(yōu)秀的,相對于大規(guī)模的數(shù)據(jù)集只要掌握好正確的方法,就能讓在數(shù)據(jù)處理時間上節(jié)省很多很多的時間。

Pandas 是建立在 NumPy 數(shù)組結(jié)構(gòu)之上的,許多操作都是在 C 中執(zhí)行的,要么通過 NumPy,要么通過 Pandas 自己的 Python 擴展模塊庫,這些模塊用 Cython 編寫并編譯為 C。理論上來說處理速度應(yīng)該是很快的。

那么為什么同樣一份數(shù)據(jù)由2個人處理,在設(shè)備相同的情況下處理時間會出現(xiàn)天差地別呢?

需要明確的是,這不是關(guān)于如何過度優(yōu)化 Pandas 代碼的指南。如果使用得當(dāng) Pandas 已經(jīng)構(gòu)建為可以快速運行。此外優(yōu)化和編寫干凈的代碼之間存在很大差異。

這是以 Python 方式使用 Pandas 以充分利用其強大且易于使用的內(nèi)置功能的指南。

數(shù)據(jù)準(zhǔn)備

此示例的目標(biāo)是應(yīng)用分時能源關(guān)稅來計算一年的能源消耗總成本。 也就是說,在一天中的不同時間,電價會有所不同,因此任務(wù)是將每小時消耗的電量乘以消耗該小時的正確價格。

從一個包含兩列的 CSV 文件中讀取數(shù)據(jù),一列用于日期加時間,另一列用于以千瓦時 (kWh) 為單位消耗的電能。

日期時間數(shù)據(jù)優(yōu)化

import pandas as pd
df = pd.read_csv('數(shù)據(jù)科學(xué)必備Pandas實操數(shù)據(jù)處理加速技巧匯總/demand_profile.csv')
df.head()
     date_time  energy_kwh
0  1/1/13 0:00       0.586
1  1/1/13 1:00       0.580
2  1/1/13 2:00       0.572
3  1/1/13 3:00       0.596
4  1/1/13 4:00       0.592

乍一看這看起來不錯,但有一個小問題。 Pandas 和 NumPy 有一個 dtypes(數(shù)據(jù)類型)的概念。 如果未指定任何參數(shù),則 date_time 將采用 object dtype。

df.dtypes
date_time      object
energy_kwh    float64
dtype: object

type(df.iat[0, 0])
str

object 不僅是 str 的容器,而且是任何不能完全適合一種數(shù)據(jù)類型的列的容器。將日期作為字符串處理會既費力又低效(這也會導(dǎo)致內(nèi)存效率低下)。為了處理時間序列數(shù)據(jù),需要將 date_time 列格式化為日期時間對象數(shù)組( Timestamp)。

df['date_time'] = pd.to_datetime(df['date_time'])
df['date_time'].dtype
datetime64[ns]

現(xiàn)在有一個名為 df 的 DataFrame,有兩列和一個用于引用行的數(shù)字索引。

df.head()
               date_time    energy_kwh
0    2013-01-01 00:00:00         0.586
1    2013-01-01 01:00:00         0.580
2    2013-01-01 02:00:00         0.572
3    2013-01-01 03:00:00         0.596
4    2013-01-01 04:00:00         0.592

使用 Jupyter 自帶的 %%time 計時裝飾器進(jìn)行測試。

def convert(df, column_name):
	return pd.to_datetime(df[column_name])

%%time
df['date_time'] = convert(df, 'date_time')

Wall time: 663 ms

def convert_with_format(df, column_name):
	return pd.to_datetime(df[column_name],format='%d/%m/%y %H:%M')

%%time
df['date_time'] = convert(df, 'date_time')

Wall time: 1.99 ms

處理效率提高將近350倍。如果在處理大規(guī)模數(shù)據(jù)的情況下,處理數(shù)據(jù)的時間會無限的放大。

數(shù)據(jù)的簡單循環(huán)

既然日期和時間格式處理完畢,就可以著手計算電費了。成本因小時而異,因此需要有條件地將成本因素應(yīng)用于一天中的每個小時。

在此示例中,使用時間成本將定義成三個部分。

data_type = {
    # 高峰
    "Peak":{"Cents per kWh":28,"Time Range":"17:00 to 24:00"},
    # 正常時段
    "Shoulder":{"Cents per kWh":20,"Time Range":"7:00 to 17:00"},
    # 非高峰
    "Off-Peak":{"Cents per kWh":12,"Time Range":"0:00 to 7:00"}, 
}

如果價格是一天中每小時每千瓦時 28 美分。

df['cost_cents'] = df['energy_kwh'] * 28

               date_time    energy_kwh       cost_cents
0    2013-01-01 00:00:00         0.586           16.408
1    2013-01-01 01:00:00         0.580           16.240
2    2013-01-01 02:00:00         0.572           16.016
3    2013-01-01 03:00:00         0.596           16.688
4    2013-01-01 04:00:00         0.592           16.576
...

但是成本計算取決于一天中的不同時間。這就是你會看到很多人以意想不到的方式使用 Pandas 的地方,通過編寫一個循環(huán)來進(jìn)行條件計算。

def apply_tariff(kwh, hour):
    """計算給定小時的電費"""    
    if 0 <= hour < 7:
        rate = 12
    elif 7 <= hour < 17:
        rate = 20
    elif 17 <= hour < 24:
        rate = 28
    else:
        raise ValueError(f'無效時間: {hour}')
    return rate * kwh

def apply_tariff(kwh, hour):
    """計算給定小時的電費"""    
    if 0 <= hour < 7:
        rate = 12
    elif 7 <= hour < 17:
        rate = 20
    elif 17 <= hour < 24:
        rate = 28
    else:
        raise ValueError(f'無效時間: {hour}')
    return rate * kwh

def apply_tariff_loop(df):
    energy_cost_list = []
    for i in range(len(df)):
    	# 循環(huán)數(shù)據(jù)直接修改df
        energy_used = df.iloc[i]['energy_kwh']
        hour = df.iloc[i]['date_time'].hour
        energy_cost = apply_tariff(energy_used, hour)
        energy_cost_list.append(energy_cost)

    df['cost_cents'] = energy_cost_list

Wall time: 2.59 s

循環(huán) .itertuples() 和 .iterrows() 方法

Pandas 實際上 for i in range(len(df)) 通過引入 DataFrame.itertuples() 和 DataFrame.iterrows() 方法使語法就可能顯得多余,這些都是yield一次一行的生成器方法。

.itertuples() 為每一行生成一個命名元組,行的索引值作為元組的第一個元素。 名稱元組是來自 Python 集合模塊的數(shù)據(jù)結(jié)構(gòu),其行為類似于 Python 元組,但具有可通過屬性查找訪問的字段。

.iterrows() 為 DataFrame 中的每一行生成 (index, Series) 對(元組)。

def apply_tariff_iterrows(df):
    energy_cost_list = []
    for index, row in df.iterrows():
        energy_used = row['energy_kwh']
        hour = row['date_time'].hour
        energy_cost = apply_tariff(energy_used, hour)
        energy_cost_list.append(energy_cost)
    df['cost_cents'] = energy_cost_list

%%time
apply_tariff_iterrows(df)

Wall time: 808 ms

速度提高又3倍之多。

.apply() 方法

可以使用 .apply() 方法進(jìn)一步改進(jìn)此操作。 Pandas 的 .apply() 方法采用函數(shù)(可調(diào)用對象)并將它們沿 DataFrame 的軸(所有行或所有列)應(yīng)用。

lambda 函數(shù)將兩列數(shù)據(jù)傳遞給 apply_tariff()。

def apply_tariff_withapply(df):
    df['cost_cents'] = df.apply(
        lambda row: apply_tariff(
            kwh=row['energy_kwh'],
            hour=row['date_time'].hour),
        axis=1)

%%time
apply_tariff_withapply(df)

Wall time: 181 ms

.apply() 的語法優(yōu)勢很明顯,代碼簡潔、易讀、明確。在這種情況下所用時間大約是該 .iterrows() 方法的4分之一。

.isin() 數(shù)據(jù)選擇

但是如何在 Pandas 中將條件計算應(yīng)用為矢量化操作呢?一個技巧是根據(jù)的條件選擇和分組 DataFrame 的部分,然后對每個選定的組應(yīng)用矢量化操作。

使用 Pandas 的.isin()方法選擇行,然后在矢量化操作中應(yīng)用。在執(zhí)行此操作之前,如果將 date_time 列設(shè)置為 DataFrame 的索引會更方便。

df.set_index('date_time', inplace=True)

def apply_tariff_isin(df):
    peak_hours = df.index.hour.isin(range(17, 24))
    shoulder_hours = df.index.hour.isin(range(7, 17))
    off_peak_hours = df.index.hour.isin(range(0, 7))

    df.loc[peak_hours, 'cost_cents'] = df.loc[peak_hours, 'energy_kwh'] * 28
    df.loc[shoulder_hours,'cost_cents'] = df.loc[shoulder_hours, 'energy_kwh'] * 20
    df.loc[off_peak_hours,'cost_cents'] = df.loc[off_peak_hours, 'energy_kwh'] * 12

%%time
apply_tariff_isin(df)

Wall time: 53.5 ms

其中整個過程方法返回一個布爾列表。

[False, False, False, ..., True, True, True]

.cut() 數(shù)據(jù)分箱

設(shè)置時間切分的列表和對那個計算的函數(shù)公式,讓操作起來更簡單,但是這個對于新手來說代碼閱讀起來有些困難。

def apply_tariff_cut(df):
    cents_per_kwh = pd.cut(x=df.index.hour,
                           bins=[0, 7, 17, 24],
                           include_lowest=True,
                           labels=[12, 20, 28]).astype(int)
    df['cost_cents'] = cents_per_kwh * df['energy_kwh']
    
%%time
apply_tariff_cut(df)

Wall time: 2.99 ms

Numpy 方法處理

Pandas Series 和 DataFrames 是在 NumPy 庫之上設(shè)計的。這為提供了更大的計算靈活性,因為 Pandas 可以與 NumPy 數(shù)組和操作無縫協(xié)作。

使用 NumPy 的digitize()函數(shù)。它與 Pandas 的相似之處cut()在于數(shù)據(jù)將被分箱,但這次它將由一個索引數(shù)組表示,該數(shù)組表示每個小時屬于哪個箱。然后將這些索引應(yīng)用于價格數(shù)組。

import numpy as np

def apply_tariff_digitize(df):
    prices = np.array([12, 20, 28])
    bins = np.digitize(df.index.hour.values, bins=[7, 17, 24])
    df['cost_cents'] = prices[bins] * df['energy_kwh'].values

%%time
apply_tariff_digitize(df)

Wall time: 1.99 ms

處理效率比較

對比一下上面幾種不同的處理方式的效率吧。

功能運行時間(秒)
apply_tariff_loop()2.59 s
apply_tariff_iterrows()808 ms
apply_tariff_withapply()181 ms
apply_tariff_isin()53.5 ms
apply_tariff_cut()2.99 ms
apply_tariff_digitize()1.99 ms

HDFStore 防止重新處理

通常構(gòu)建復(fù)雜的數(shù)據(jù)模型時,對數(shù)據(jù)進(jìn)行一些預(yù)處理會很方便。如果有 10 年的分鐘頻率用電量數(shù)據(jù),即指定了格式參數(shù)簡單地將日期和時間轉(zhuǎn)換為日期時間也可能需要 20 分鐘。只需要這樣做一次而不是每次運行模型時都需要進(jìn)行測試或分析。

可以在這里做的一件非常有用的事情是預(yù)處理,然后以處理后的形式存儲數(shù)據(jù),以便在需要時使用。但是如何才能以正確的格式存儲數(shù)據(jù)而無需再次重新處理呢?如果要保存為 CSV 只會丟失您的日期時間對象,并且在再次訪問時必須重新處理它。

Pandas 有一個內(nèi)置的解決方案使用 HDF5,一種專為存儲表格數(shù)據(jù)數(shù)組而設(shè)計的高性能存儲格式。Pandas 的 HDFStore 類允許將 DataFrame 存儲在 HDF5 文件中,以便可以有效地訪問它,同時仍保留列類型和其他元數(shù)據(jù)。dict 是一個類似字典的類,因此可以像對 Python對象一樣進(jìn)行讀寫。

將預(yù)處理的耗電量 DataFrame 存儲df在 HDF5 文件中。

data_store = pd.HDFStore('processed_data.h5')

# 將 DataFrame 放入對象中,將鍵設(shè)置為 preprocessed_df 
data_store['preprocessed_df'] = df
data_store.close()

從 HDF5 文件訪問數(shù)據(jù)的方法,并保留數(shù)據(jù)類型。

data_store = pd.HDFStore('processed_data.h5')

preprocessed_df = data_store['preprocessed_df']
data_store.close()

到此這篇關(guān)于Pandas數(shù)據(jù)處理加速技巧匯總的文章就介紹到這了,更多相關(guān)Pandas數(shù)據(jù)處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python實現(xiàn)計數(shù)排序與桶排序?qū)嵗a

    python實現(xiàn)計數(shù)排序與桶排序?qū)嵗a

    這篇文章主要介紹了python計數(shù)排序與桶排序,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Python如何批量處理經(jīng)緯度數(shù)據(jù)并生成位置信息

    Python如何批量處理經(jīng)緯度數(shù)據(jù)并生成位置信息

    這篇文章主要介紹了Python如何批量處理經(jīng)緯度數(shù)據(jù)并生成位置信息問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Python利用socket實現(xiàn)多進(jìn)程的端口掃描器

    Python利用socket實現(xiàn)多進(jìn)程的端口掃描器

    作為開發(fā)人員經(jīng)常需要查看服務(wù)的端口開啟狀態(tài)判斷服務(wù)是否宕機。特別是部署的服務(wù)比較多的情況下,可能存在幾個甚至幾十個服務(wù)端口的占用。所以本文將利用socket實現(xiàn)多進(jìn)程的端口掃描器,需要的可以參考一下
    2022-12-12
  • 解決vscode python print 輸出窗口中文亂碼的問題

    解決vscode python print 輸出窗口中文亂碼的問題

    今天小編就為大家分享一篇解決vscode python print 輸出窗口中文亂碼的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • python中有幫助函數(shù)嗎

    python中有幫助函數(shù)嗎

    在本篇文章里小編給大家分享的是一篇關(guān)于python幫助函數(shù)詳解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2020-06-06
  • python 安裝教程之Pycharm安裝及配置字體主題,換行,自動更新

    python 安裝教程之Pycharm安裝及配置字體主題,換行,自動更新

    這篇文章主要介紹了python 安裝教程之Pycharm安裝及配置字體主題,換行,自動更新,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • Python將Excel轉(zhuǎn)換為多種圖片格式的方法(PNG, JPG, BMP, SVG)

    Python將Excel轉(zhuǎn)換為多種圖片格式的方法(PNG, JPG, BMP, SVG)

    有時,你可能希望以圖片形式分享Excel數(shù)據(jù),以防止他人對數(shù)據(jù)進(jìn)行修改或編輯,將Excel轉(zhuǎn)換為圖片可以將數(shù)據(jù)鎖定為靜態(tài)圖片,確保數(shù)據(jù)的完整性和準(zhǔn)確性,這篇文章將探討如何使用Python實現(xiàn)將Excel工作表轉(zhuǎn)換為多種圖片格式,如PNG,JPG,BMP和SVG,需要的朋友可以參考下
    2025-03-03
  • Python&Matlab實現(xiàn)櫻花的繪制

    Python&Matlab實現(xiàn)櫻花的繪制

    正值櫻花飄落的季節(jié),本文將利用Python和Matlab分別繪制一顆櫻花樹,文中的示例代碼講解詳細(xì),感興趣的小伙伴快跟隨小編一起動手嘗試一下
    2022-04-04
  • Python logging模塊原理解析及應(yīng)用

    Python logging模塊原理解析及應(yīng)用

    這篇文章主要介紹了Python logging模塊原理解析及應(yīng)用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-08-08
  • Python中Get()函數(shù)用法舉例介紹

    Python中Get()函數(shù)用法舉例介紹

    這篇文章主要給大家介紹了關(guān)于Python中Get()函數(shù)用法的相關(guān)資料,Python get()函數(shù)是一個非常重要的函數(shù),它可以幫助我們從字典中獲取對應(yīng)鍵的值,避免了因為鍵不存在而發(fā)生錯誤的情況,需要的朋友可以參考下
    2023-10-10

最新評論

鱼台县| 丁青县| 晋宁县| 师宗县| 凤山市| 柞水县| 谢通门县| 开化县| 丘北县| 韶关市| 绥芬河市| 曲阜市| 肇州县| 黔东| 项城市| 望奎县| 漯河市| 罗平县| 高陵县| 仙游县| 武宁县| 常宁市| 荆州市| 株洲市| 西充县| 南华县| 威信县| 龙州县| 上饶市| 洞口县| 沛县| 乡宁县| 朔州市| 临沭县| 封开县| 通江县| 政和县| 文成县| 平陆县| 襄垣县| 司法|