ibeautiful
2022-08-16 15:34:32
我有多個大型數據幀(大約3GB csv文件,每個大約1.5億行),其中包含Unix樣式的時間戳和隨機生成的觀察ID。每個觀察可以/將在不同的時間多次發生。它們看起來像這樣: time_utc obs_id0 1564617600 aabthssv1 1564617601 vvvx7ths2 1564618501 optnhfsa3 1564619678 aabthssv4 1564619998 abtzsnwe ...我現在想為了分析觀測的時間發展,得到一個數據幀,其中包含每個觀測值ID的列和可以更改的時間箱的行,例如1小時,如下所示:time_bin aabthssv vvvx7ths optnhfsa ...1 1 1 12 1 0 0 ...我試圖通過創建一個時間戳起點的numpy數組來做到這一點,然后將value_counts添加到一個新的空數據幀中,以選擇該箱中的所有行。這會遇到內存錯誤。我已經嘗試了更多的預清理,但即使將原始數據的大小減少三分之一(因此2GB,1億行)仍然會發生內存錯誤。SLICE_SIZE = 3600 # example value of 1hslice_startpoints = np.arange(START_TIME, END_TIME+1-SLICE_SIZE, SLICE_SIZE)agg_df = pd.DataFrame()for timeslice in slice_startpoints: temp_slice = raw_data[raw_data['time_utc'].between(timeslice, timeslice + SLICE_SIZE)] temp_counts = temp_slice['obs_id'].value_counts() agg_df = agg_df.append(temp_counts) temp_index = raw_data[raw_data['time_utc'].between(timeslice, timeslice + SLICE_SIZE)].index raw_data.drop(temp_index, inplace=True)有沒有辦法更有效地做到這一點,或者更確切地說,讓它根本有效?編輯:我根據使用交叉表的建議找到了有效的方法來做到這一點。文件大小不需要減小。使用以下代碼得出的結果正是我正在尋找的結果。df['binned'] = pd.cut(df['time_utc'], bins=slice_startpoints, include_lowest=True, labels=slice_startpoints[1:])df.groupby('binned')['obs_id'].value_counts().unstack().fillna(0)
2 回答

猛跑小豬
TA貢獻1858條經驗 獲得超8個贊
您可以嘗試使用交叉表進行剪切:
slice_startpoints = np.arange(START_TIME, END_TIME+SLICE_SIZE, SLICE_SIZE)
print (slice_startpoints)
df['binned'] = pd.cut(df['time_utc'],
bins=slice_startpoints,
include_lowest=True,
labels=slice_startpoints[1:])
df = pd.crosstab(df['binned'], df['obs_id'])

尚方寶劍之說
TA貢獻1788條經驗 獲得超4個贊
您可以使用“塊”迭代器讀取大型.csv,然后對塊而不是整個.csv文件執行計算。塊大小定義單個塊中的行數。這樣,您就有了一個很好的句柄來控制內存使用情況。缺點是,您將必須添加一些邏輯來合并塊的結果。
import pandas as pd
df_chunk = pd.read_csv('file.csv', chunksize=1000)
for chunk in df_chunk:
print(chunk)
添加回答
舉報
0/150
提交
取消