[英]Speeding up the python performance
添加由建議代碼繪制的 100k 原始數據和 plot我有以下代碼,分析 100K 行數據,顯示 output 需要 3 分鍾。 問題出在 for 循環中,程序需要檢查兩個指標,然后根據它采取行動。 數據是交易所的買入/賣出/na 記錄,我想繪制買入與賣出等等。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv('gco.csv', encoding ='utf-16 LE')
x = data.index.size
data['Money'] = data['Last']*data['Volume']
data['Date'] = data['Time']
# Creating date column
data['Date'] = data['Date'].map(lambda x: x[0:10])
# Creating a dedicated database
my_df = pd.DataFrame(columns =['Buy','Sell','NA'])
#calculate the Buy column
avai_dates = pd.unique(data.Date)
y = len(avai_dates)
my_df = pd.DataFrame(index=np.arange(0, y), columns =['Buy','Sell','NA'])
my_df[:]=0
for j in range(y):
for i in range(x):
if data.Date[i] == avai_dates[j] and data.Type[i] == 'Buy':
my_df.Buy[j] += data.Money[i]
for i in range(x):
if data.Date[i] == avai_dates[j] and data.Type[i] == 'Sell':
my_df.Sell[j] += data.Money[i]
for i in range(x):
if data.Date[i] == avai_dates[j] and data.Type[i] == 'Buy/Sell':
my_df.NA[j] += data.Money[i]
new_df = my_df[(my_df.T != 0).any()]
z = len(new_df)
xm = np.arange(0, z)
plt.plot(xm, new_df.Buy, 'green')
plt.plot(xm, new_df.Sell, 'red')
plt.plot(xm, new_df.NA, 'yellow')
plt.xlabel('Dates', fontsize = 15)
plt.ylabel('Money Volumes', fontsize = 15)
plt.title('Buy vs. Sell Vs. NA')
plt.grid()
plt.show()
ax = plt.subplot(111)
ax.bar(xm-0.2, new_df.Buy, width = 0.2, color = 'g')
ax.bar(xm,new_df.Sell, width = 0.2 , color = 'r')
ax.bar(xm+0.2,new_df.NA, width = 0.2, color = 'y')
您正在做的是按Time
和Type
對數據點進行分組並聚合它們。 Pandas 具有執行此操作的內置功能。
您可以替換所有這些代碼:
# Creating a dedicated database
my_df = pd.DataFrame(columns =['Buy','Sell','NA'])
#calculate the Buy column
avai_dates = pd.unique(data.Date)
y = len(avai_dates)
my_df = pd.DataFrame(index=np.arange(0, y), columns =['Buy','Sell','NA'])
my_df[:]=0
for j in range(y):
for i in range(x):
if data.Date[i] == avai_dates[j] and data.Type[i] == 'Buy':
my_df.Buy[j] += data.Money[i]
for i in range(x):
if data.Date[i] == avai_dates[j] and data.Type[i] == 'Sell':
my_df.Sell[j] += data.Money[i]
for i in range(x):
if data.Date[i] == avai_dates[j] and data.Type[i] == 'Buy/Sell':
my_df.NA[j] += data.Money[i]
new_df = my_df[(my_df.T != 0).any()]
有了這個聲明:
new_df = data.groupby(["Time", "Type"]).agg({'Money':['sum']})["Money","sum"].unstack(fill_value=0)
data.groupby(["Time", "Type"])
這將按Time
和Type
對數據進行分層分組。 有關這方面的更多信息,請查看DataFrame.groupby()
文檔。
.agg({'Money':['sum']})
這通過匯總來匯總每個組中的貨幣值。 您可以只使用.agg('sum')
但這也會聚合 'Last' 和 'Volume' 的值
["Money","sum"]
然后我們只需解壓縮列即可得到原始總和。 這幾乎為您提供了結果,但是它堆疊了Type
組:
Time Type
2020:12:12 Buy 1000
Sell 1000
2020:12:13 Buy 4400
Sell 2200
2020:12:14 Sell 4680
2020:12:15 Buy 2860
Sell 1430
2020:12:16 Buy/Sell 6400
2020:12:17 Buy 7140
2020:12:18 Buy/Sell 770
2020:12:19 Buy 810
Sell 1620
2020:12:20 Buy 2400
Sell 1200
2020:12:21 Buy 1210
2020:12:22 Buy 1200
Sell 1200
Name: (Money, sum), dtype: int64
您現在可以使用最終的拆垛 function 來獲得最終的 dataframe。 通過設置fill_value=0
可以確保未定義的值設置為0
而不是nan
.unstack(fill_value=0)
我根據您提供的少量信息創建了一些玩具數據,並通過單線運行它,這就是您得到的。
Type Buy Buy/Sell Sell
Time
2020:12:12 1000 0 1000
2020:12:13 4400 0 2200
2020:12:14 0 0 4680
2020:12:15 2860 0 1430
2020:12:16 0 6400 0
2020:12:17 7140 0 0
2020:12:18 0 770 0
2020:12:19 810 0 1620
2020:12:20 2400 0 1200
2020:12:21 1210 0 0
2020:12:22 1200 0 1200
它基本上與您計算的原始new_df
幾乎相同,除了它將Time
值保留為索引並且 Buy/Sell Type 標記為Buy/Sell
而不是NA
。 當然,如果您願意,可以刪除Time
列並重命名Buy/Sell
,方法是將其附加到單行中:
.reset_index().drop("Time",axis=1).rename(columns={"Buy/Sell":"NA"})
如果這提供了任何加速,請在評論中告訴我。 如果您的數據框非常大,您可能不得不求助於其他技術,例如批量分析數據、並行處理或自定義numba
處理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.