[英]Is there a faster way to insert dataframe to SQL using python?
[英]Python: Faster way to insert rows into a DataFrame at specific locations?
我有一個約40,000行的DataFrame。 DataFrame大致類似於:
Unix Time UTC Val. 1 Val. 2 Val. 3
1 1518544176.927486 2018-02-13 17:49:36.927486 5.00 0.25 2.00
2 1518544176.929897 2018-02-13 17:49:36.929897 4.50 1.00 3.00
3 1518544176.932310 2018-02-13 17:49:36.932310 4.00 0.75 1.75
...
列<class 'numpy.float64'>
為<class 'numpy.float64'>
。 列1是<class 'pandas._libs.tslib.Timestamp'>
。 當人們繪制任何數據列與時間的關系時,我們會看到一個波形。 但是,收購中偶爾會有中斷。 例如,我們可能有:
Unix Time UTC Val. 1 Val. 2 Val. 3
576 1518544181.755085 2018-02-13 17:49:41.755085 0.10 0.01 0.93
577 1518544182.041129 2018-02-13 17:49:42.041129 0.11 0.02 0.95
...
可以看到,讀數576和577之間有大約0.3 s的間隙。問題在於,繪制數據時,即使沒有數據,matplotlib也會連接點。 這個問題的解決方案已經在Stack Overflow和在線一般會員的其他問題中得到解決,盡管我不喜歡...嗯,其中任何一個,最好的選擇似乎是將NaN插入到數據缺口。 由於matplotlib不會繪制NaN,因此這是一種狡猾的方法,可以欺騙它使您的繪制更加逼真。
為此,我首先查找前兩個讀數之間的時間差(這是安全的),然后將該值的兩倍用作“是否存在差距?”的指標。 然后,我遍歷DataFrame,檢查差距。 找到一個后,我在數據列中創建了一個NaN臨時行,並在時間列中的采集間隔的中間創建了時間值。 然后,我修改由舊框架構成的新DataFrame,並添加此行。 這看起來像在這里:
df2 = df.copy()
for i, row in df.iterrows():
# The following code checks the delta-t of all timestamp pairs.
# We have i > 0 because it can't activate on the first entry.
if i > 0:
delta_t_unix = row['Unix Time'] - prev_timestamp_unix
delta_t_utc = row['UTC'] - prev_timestamp_utc
# If delta_t_unix > the allowed data gap, add new timestamps and NaNs.
if delta_t_unix > allowed_gap:
time_unix = row['Unix Time'] - (delta_t_unix / 2.0)
time_utc = row['UTC'] - (delta_t_utc / 2.0)
val1 = np.nan
val2 = np.nan
val3 = np.nan
new_row = pd.DataFrame({'Unix Time': time_unix, 'UTC': time_utc,
'Val. 1': val1, 'Val. 2': val2,
'Val. 3': val3}, index = [i])
df2 = pd.concat([df2.ix[:i-1], new_row,
df2.ix[i:]]).reset_index(drop = True)
# Set the previous timestamp for use in the beginning of the loop.
prev_timestamp_unix = row[timestamp_unix]
prev_timestamp_utc = row[timestamp_utc]
# Make the final DataFrame with the completed lists.
df2 = df2[['Unix Time', 'UTC', 'Val. 1', 'Val. 2', 'Val. 3']]
多虧了這個問題 ,目前大約需要4.5秒(以前大約需要6.5秒,因為我很愚蠢地遍歷並創建每列的新列表,然后從中創建一個新的DataFrame)。 但是,這仍然比我期望或喜歡的要慢得多。 有人對如何加快速度有任何想法嗎? 我對Pandas和DataFrames還是很陌生,所以我相信這會更好。 謝謝!
編輯:值得一提的是,如果我刪除了datetime
列,它將把時間分成兩半(盡管不幸的是,我實際上無法刪除它)。
您可以使用以下方法將采樣重新采樣到2.4ms:
df['utc_time'] = pd.to_datetime(df['utc_time'])
df.set_index(df['utc_time'])[['val1','val2','val3']].resample('2.4ms', loffset='1.2ms').mean().reset_index()
可以加快速度的一些事情:
df.itertuples()
代替df.iterrows()
,它可能會在一定程度上縮短執行時間。 如果您可以發布改進,我將不勝感激,但根據我的經驗,在我測試的案例中,這是一個巨大的差異(將10倍的改進,使循環內的指令更簡單)。
不要使用pd.concat
將行放在一起,而是創建一個元組列表,然后僅在從該列表循環之后才生成DataFrame。
for i, unix_time, utc_time, val1, val2, val3 in df.itertuples(): list_of_values = [] if i > 0: delta_t_unix = unix_time - prev_timestamp_unix delta_t_utc = utc_time - prev_timestamp_utc if delta_t_unix > allowed_gap: new_time_unix = unix_time - (delta_t_unix / 2.0) new_time_utc = utc_time - (delta_t_utc / 2.0) list_of_values.append((new_time_unix, new_time_utc, np.nan, np.nan, np.nan)) # Set the previous timestamp for use in the beginning of the loop. prev_timestamp_unix = unix_time prev_timestamp_utc = utc_time list_of_values.append(((unix_time , utc_time, val1, val2, val3)) df2 = pd.DataFrame(list_of_values, columns=['Unix Time', 'UTC', 'Val. 1', 'Val. 2', 'Val. 3'])
那可能會大大加快速度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.