簡體   English   中英

在一個循環中組合來自兩個熊貓數據幀的兩個切片的最快方法?

[英]Fastest way to combine two slices from two pandas dataframes in a loop?

我有一個個人ID列表,對於每個ID,我想從兩個不同的數據框中提取所有可用信息。 另外,信息的類型也有ID,我只希望每個人的ID有特定的信息ID。 這是我目前正在執行的操作:

    new_table = []
    for i in range(ranges):

        slice = pd.concat([df1[sp.logical_and(df1.person.values == persons[i],
                                                   df1['info_id'].isin(info_ids))],
                df2[sp.logical_and(df2.person.values == persons[i],
                                      df2['info_id'].isin(info_ids))]], ignore_index=True)

        if len(list(set(slice['info_ids']))) < amount_of_info_needed:
                    continue
        else:
            full_time_range = max(slice['age_days']) - min(slice['age_days']) 
            if full_time_range <= 1460:
                new_table.append(slice)
            else:
                window_end = min(slice['age_days']) + 1460
                slice = slice[slice.age_days < window_end+1]
                if len(list(set(slice['info_id']))) < amount_of_info_needed:
                    continue
                else:
                    new_table.append(slice)
    #return new_table
    new_table = pd.concat(new_table, axis=0)
    new_table = new_table.groupby(['person', 'info_id']).agg(np.mean).reset_index()
    new_table.to_sql('person_info_within4yrs', engine, if_exists='append', index=False, 
                 dtype={'person': types.NVARCHAR(32), 'value': types.NVARCHAR(4000)})

我讀到有關由於二次時間而沒有在循環中使用pd.concat的信息,但是我嘗試將數據幀轉換為數組並對其進行切片和連接,但這比使用pd.concat還要慢。 在用%lprun對每行進行性能分析之后,循環中的pd.concat / logical_and操作消耗了所有時間。 此代碼也比將.loc與兩個數據幀同時將兩個切片串聯在一起要快。 在if-else塊之后,我附加到列表,最后將列表變成數據框。

編輯:這是我在做什么的一個例子。 目標是通過person_id和info_id從兩個數據幀中進行切片,組合這些切片,並將組合的切片附加到列表中,然后我將其轉換回數據框並導出到SQL表。 if-else塊也很重要,但是從我的分析來看,它們幾乎不需要任何時間,因此我將不對其進行詳細描述。

df1.head()
    person  info_id value   age_days
0   000012eae6ea403ca564e87b8d44d0bb    0   100.0   28801
1   000012eae6ea403ca564e87b8d44d0bb    0   100.0   28803
2   000012eae6ea403ca564e87b8d44d0bb    0   100.0   28804
3   000012eae6ea403ca564e87b8d44d0bb    0   100.0   28805
4   000012eae6ea403ca564e87b8d44d0bb    0   100.0   28806

df2.head()
    person  info_id value   age_days
0   00000554787a3cb38131c3c38578cacf    4v  97.0    12726
1   00000554787a3cb38131c3c38578cacf    14v 180.3   12726
2   00000554787a3cb38131c3c38578cacf    9v  2.0 12726
3   00000554787a3cb38131c3c38578cacf    3v  20.0    12726
4   00000554787a3cb38131c3c38578cacf    0v  71.0    12726

我接受了Parfait的建議,首先將兩個數據框串聯在一起,然后一位同事給了我一個遍歷該數據框的解決方案。 數據幀由約1.17億行和約246,000個人ID組成。 我的同事的解決方案是創建一個字典,其中每個鍵都是一個人員ID,每個鍵的值是該數據框中該人員ID的行索引的列表。 然后,您可以使用.iloc通過引用字典中的值對數據幀進行切片。 在大約一小時內完成運行。

idx = df1['person'].reset_index().groupby('person')['index'].apply(tuple).to_dict()

for i in range(ranges):
    mrn_slice = df1.iloc[list(idx.values()[i])]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM