2016-08-25 48 views
1

我對Python中的「for」語句非常新,我不能得到我認爲應該很簡單的東西。我的代碼,我有是:使用「for」語句使用字符串凝聚重複代碼 - Python

import pandas as pd 

df1 = pd.DataFrame({'Column1' : pd.Series([1,2,3,4,5,6])}) 
df2 = pd.DataFrame({'Column1' : pd.Series([1,2,3,4,5,6])}) 
df3 = pd.DataFrame({'Column1' : pd.Series([1,2,3,4,5,6])}) 

DF1 = pd.DataFrame({'Column1' : pd.Series([1,2,3,4,5,6])}) 
DF2 = pd.DataFrame({'Column1' : pd.Series([1,2,3,4,5,6])}) 
DF3 = pd.DataFrame({'Column1' : pd.Series([1,2,3,4,5,6])}) 

然後:

A1 = len(df1.loc[df1['Column1'] <= DF1['Column1'].iloc[2]]) 
Z1 = len(df1.loc[df1['Column1'] >= DF1['Column1'].iloc[3]]) 

A2 = len(df2.loc[df2['Column1'] <= DF2['Column1'].iloc[2]]) 
Z2 = len(df2.loc[df2['Column1'] >= DF2['Column1'].iloc[3]]) 

A3 = len(df3.loc[df3['Column1'] <= DF3['Column1'].iloc[2]]) 
Z3 = len(df3.loc[df3['Column1'] >= DF3['Column1'].iloc[3]]) 

正如你可以看到,這是一個很大的重複代碼,只需識別號是不同的。所以我在「爲」語句的第一次嘗試是:

Numbers = [1,2,3] 

for i in Numbers: 
    "A" + str(i) = len("df" + str(i).loc["df" + str(i)['Column1'] <= "DF" + str(i)['Column1'].iloc[2]]) 
    "Z" + str(i) = len("df" + str(i).loc["df" + str(i)['Column1'] >= "DF" + str(i)['Column1'].iloc[3]]) 

這產生了語法錯誤:「不能分配給操作」。所以我嘗試過:

Numbers = [1,2,3] 

for i in Numbers: 
    A = "A" + str(i) 
    Z = "Z" + str(i) 
    A = len("df" + str(i).loc["df" + str(i)['Column1'] <= "DF" + str(i)['Column1'].iloc[2]]) 
    Z = len("df" + str(i).loc["df" + str(i)['Column1'] >= "DF" + str(i)['Column1'].iloc[3]]) 

這產生了AttributeError:'str'對象沒有屬性'loc'。我嘗試了一些其他的東西,如:

Numbers = [1,2,3] 

for i in Numbers: 
    A = "A" + str(i) 
    Z = "Z" + str(i) 
    df = "df" + str(i) 
    DF = "DF" + str(i) 
    A = len(df.loc[df['Column1'] <= DF['Column1'].iloc[2]]) 
    Z = len(df.loc[df['Column1'] <= DF['Column1'].iloc[3]]) 

但這只是給了我相同的錯誤。最後我想是這樣的:

Numbers = [1,2,3] 

for i in Numbers: 
    Ai = len(dfi.loc[dfi['Column1'] <= DFi['Column1'].iloc[2]]) 
    Zi = len(dfi.loc[dfi['Column1'] <= DFi['Column1'].iloc[3]]) 

在哪裏,如果我輸入的輸出是等價的:

A1 = len(df1.loc[df1['Column1'] <= DF1['Column1'].iloc[2]]) 
Z1 = len(df1.loc[df1['Column1'] >= DF1['Column1'].iloc[3]]) 

A2 = len(df2.loc[df1['Column1'] <= DF2['Column1'].iloc[2]]) 
Z2 = len(df2.loc[df1['Column1'] >= DF2['Column1'].iloc[3]]) 

A3 = len(df3.loc[df3['Column1'] <= DF3['Column1'].iloc[2]]) 
Z3 = len(df3.loc[df3['Column1'] >= DF3['Column1'].iloc[3]]) 
+0

的可能的複製[你怎麼能動態地通過一個while循環創建Python中的變量?(http://stackoverflow.com/questions/5036700/how-can-you-dynamically-create-variables-in -python-via-while-loop) –

+0

@ŁukaszRogalski這將如何工作,我只需將「x」定義爲[26,45,46,47,51,58,64,65],然後鍵入「Ax = len(Hx.loc [Hx ['EKG-evt'] <= Ix [0] .iloc [0]])/ 10「? – Michael

+0

如果您將數據幀與列一起提供,而不是將列分配給每個列的命名變量,那麼這將會更好。你所要求的要求是在看起來像變量名的字符串上使用'eval'或'exec'。所有這些努力僅僅是指那些已經在你沒有共享的另一個數據框中很好地表現出來的東西。我不會浪費時間去解決這個問題。但是,如果您對原始數據提出類似問題,我會考慮它。 – piRSquared

回答

2

據「限制」來產生for循環(你可以做到這一點變數,但最好避免。見其他帖子:post_1post_2)。

而是使用此代碼來實現自己的目標,而不會產生儘可能多的變量您的需求(實際上只產生在for循環值):

# Lists of your dataframes 
Hanimals = [H26, H45, H46, H47, H51, H58, H64, H65] 
Ianimals = [I26, I45, I46, I47, I51, I58, I64, I65] 

# Generate your series using for loops iterating through your lists above 
BPM = pd.DataFrame({'BPM_Base':pd.Series([i_a for i_a in [len(i_h.loc[i_h['EKG-evt'] <=\ 
    i_i[0].iloc[0]])/10 for i_h, i_i in zip(Hanimals, Ianimals)]]), 
    'BPM_Test':pd.Series([i_z for i_z in [len(i_h.loc[i_h['EKG-evt'] >=\ 
    i_i[0].iloc[-1]])/30 for i_h, i_i in zip(Hanimals, Ianimals)]])}) 

UPDATE

更有效的方法(迭代「動物」列表只有一次):

# Lists of your dataframes 
Hanimals = [H26, H45, H46, H47, H51, H58, H64, H65] 
Ianimals = [I26, I45, I46, I47, I51, I58, I64, I65] 

# You don't need using pd.Series(), 
# just create a list of tuples: [(A26, Z26), (A45, Z45)...] and iterate over it 
BPM = pd.DataFrame({'BPM_Base':i[0], 'BPM_Test':i[1]} for i in \ 
    [(len(i_h.loc[i_h['EKG-evt'] <= i_i[0].iloc[0]])/10, 
    len(i_h.loc[i_h['EKG-evt'] >= i_i[0].iloc[-1]])/30) \ 
    for i_h, i_i in zip(Hanimals, Ianimals)]) 
+0

此代碼完美工作,鏈接的帖子也有幫助。謝謝。 – Michael

+1

很高興幫助。我用更有效的解決方案更新了答案(只有2個for循環代替了4個循環) – ragesz

0

想出了一個更好的方法來做到這一點,適合我需要。這主要是爲了能夠找到我的方法。

# Change/Add animals and conditions here, make sure they match up directly 

Animal = ['26','45','46','47','51','58','64','65', '69','72','84'] 
Cond = ['Stomach','Intestine','Stomach','Stomach','Intestine','Intestine','Intestine','Stomach','Cut','Cut','Cut']  

d = [] 

def CuSO4(): 
    for i in Animal: 

     # load in Spike data 
     A = pd.read_csv('TXT/INJ/' + i + '.txt',delimiter=r"\s+", skiprows = 15, header = None, usecols = range(1)) 
     B = pd.read_csv('TXT/EKG/' + i + '.txt', skiprows = 3) 
     C = pd.read_csv('TXT/ESO/' + i + '.txt', skiprows = 3) 
     D = pd.read_csv('TXT/TRACH/' + i + '.txt', skiprows = 3) 
     E = pd.read_csv('TXT/BP/' + i + '.txt', delimiter=r"\s+").rename(columns={"4 BP": "BP"}) 


     # Count number of beats before/after injection, divide by 10/30 minutes for average BPM. 
     F = len(B.loc[B['EKG-evt'] <= A[0].iloc[0]])/10 
     G = len(B.loc[B['EKG-evt'] >= A[0].iloc[-1]])/30 


     # Count number of esophogeal events before/after injection 
     H = len(C.loc[C['Eso-evt'] <= A[0].iloc[0]]) 
     I = len(C.loc[C['Eso-evt'] >= A[0].iloc[-1]]) 

     # Find Trach events after injection 
     J = D.loc[D['Trach-evt'] >= A[0].iloc[-1]] 

     # Count number of breaths before/after injection, divide by 10/30 min for average breaths/min 
     K = len(D.loc[D['Trach-evt'] <= A[0].iloc[0]])/10 
     L = len(J)/30 

     # Use Trach events from J to find the number of EE 
     M = pd.DataFrame(pybursts.kleinberg(J['Trach-evt'], s=4, gamma=0.1)) 
     N = M.last_valid_index() 

     # Use N and M to determine the latency, set value to MaxTime (1800s)if EE = 0 
     O = 1800 if N == 0 else M.iloc[1][1] - A[0].iloc[-1] 

     # Find BP value before/after injection, then determine the mean value 
     P = E.loc[E['Time'] <= A[0].iloc[0]] 
     Q = E.loc[E['Time'] >= A[0].iloc[-1]] 
     R = P["BP"].mean() 
     S = Q["BP"].mean() 

     # Combine all factors into one DF 
     d.append({'EE' : N, 'EE-lat' : O, 
      'BPM_Base' : F, 'BPM_Test' : G, 
      'Eso_Base' : H, 'Eso_Test' : I, 
      'Trach_Base' : K, 'Trach_Test' : L, 
      'BP_Base' : R, 'BP_Test' : S}) 

CuSO4() 

# Create shell DF with animal numbers and their conditions. 

DF = pd.DataFrame({'Animal' : pd.Series(Animal), 'Cond' : pd.Series(Cond)}) 

# Pull appended DF from CuSO4 and make it a pd.DF 
Df = pd.DataFrame(d) 

# Combine the two DF's 
df = pd.concat([DF, Df], axis=1) 
df