2016-09-29 84 views
1

我在python中有一個大的數據框,我想根據多個for循環選擇特定的行。一些列中包含列表。我的最終目標是產生了一些優化約束,並通過其他軟件通過他們:多重for循環從python中的數據框中選擇特殊行

T  S  W  Arrived Departed  
    [1,2] [4,2]  1  8   10 
    [3,4,5] [3]  1  12   18 
    [6,7] [1,2]  2  10   11 
    .  .  .  .   . 
    .  .  .  .   . 

    def Cons(row): 

    if row['W'] == w and sum(pd.Series(row['T']).isin([t])) != 0 and sum(pd.Series(row['S']).isin([s])) != 0: 
      return 1 

    for w in range(50): 
     for s in range(30): 
      for t in range(12): 
       df.Situation = df.apply(Cons, axis = 1) 
       A = df[ (df.Situation == 1) ] 
       A1 = pd.Series(A.Arrived).tolist() 
       D1 = pd.Series(A.Departed).tolist() 
       Time = tuplelist(zip(A1,D1)) 

我怎樣纔能有效地做到這一點,因爲通過多次去爲循環需要較長的時間來運行?

+0

從你的代碼來看,嵌套循環剛剛經過50 * 30 * 12 = 18000迭代。假設最內層循環的主體沒有做任何計算密集型的事情,這應該不是問題。 – xuanluong

+0

@ xuanluong,他的算法是'O(n^3)',這對大數據不是很好 - 但對於我認同的小迭代並不是那麼糟 – coder

+0

@coder嗯,大數據,但有多大? 也許OP應該給出數據量級的更多上下文。否則,立方時間複雜性是否足夠好或太慢是任何人的猜測。 – xuanluong

回答

0

目前,您正在不斷調整每個嵌套循環的數據幀,其中每次都重寫A,並且不會產生增長的結果,而只會產生最後一次迭代的結果。

但考慮創建所有範圍的交叉連接,然後檢查平等邏輯:

wdf = pd.DataFrame({'w': range(50), 'key': 1}) 
sdf = pd.DataFrame({'s': range(30), 'key': 1}) 
tdf = pd.DataFrame({'t': range(12), 'key': 1}) 

dfs = [wdf, sdf, tdf] 

# DATA FRAME OF CROSS PRODUCT w X s X T (N = 18,000) 
rangedf = reduce(lambda left,right: pd.merge(left, right, on=['key']), dfs)[['w','s','t']] 
# w s t 
# 0 0 0 0 
# 1 0 0 1 
# 2 0 0 2 
# 3 0 0 3 
# 4 0 0 4 
# ... 

def Cons(row):  
    if any((rangedf['w'].isin([row['W']])) & (rangedf['t'].isin([row['T']])) & \ 
      (rangedf['s'].isin([row['S']]))) == True: 
     return 1 

df.Situation = df.apply(Cons, axis = 1) 
A = df[ (df.Situation == 1) ].reset_index(drop=True) 
+0

非常感謝。你的代碼是否允許我在每次迭代中使用'A',因爲我想要使用它? – user36729

+0

迭代已在此處刪除。我的理解是你只想要一個* A *數據框不是18,000個!請說明你想如何使用每個* A *。 – Parfait

+0

請參閱我上面的版本。謝謝。 – user36729