2016-09-29 88 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