[英]Filter on multiple columns in pandas data frame using a loop
上下文:我在excel中有一個數據,我們通過熊貓處理該數據以進行清理,然后在ML模型中進一步使用它。 在清理過程中,我嘗試基於多個列將數據過濾為OR條件。 這組列的標題名稱是星期幾,因此這7列代表7周。 該列的標題名稱每周更改一次。 因此,我無法保持一致的代碼來自動選擇標題名稱。
我嘗試過的邏輯:我編寫了一個代碼塊,以使用該日期列打印“ OR”條件,此后,我將此打印語句復制粘貼到“數據幀索引”部分中。 以下是它的外觀:
我現在正在復制粘貼列。 但是我想我可以通過將基於類型的條件應用於列名來構建一種邏輯來標識日期列
樣本數據:
1/20/2019 1/27/2019 2/3/2019 2/10/2019 2/17/2019 2/24/2019 3/3/2019 \
0 0(80CS,8H) 0(80CS) 0(80CS) 0(80CS) 0(80CS) 0(80CS) 0(80CS)
1 0(50CS,8H) 0(50CS) 0(50CS) 0(50CS) 0(50CS) 0(50CS) 0(50CS)
2 0(40CS,8H) 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS)
3 0(40CS,8H) 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS)
4 0(40CS,8H) 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS)
5 0(40CS,8H) 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS)
6 12(25CS,8H) 15(25CS) 15(25CS) 15(25CS) 15(25CS) 15(25CS) 15(25CS)
7 11(28CS,8H) 12(28CS) 12(28CS) 12(28CS) 12(28CS) 12(28CS) 12(28CS)
8 8(30CS,8H) 10(30CS) 10(30CS) 10(30CS) 2(30CS,32T) 10(30CS) 10(30CS)
9 0(40CS,8H) 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS)
3/10/2019 3/17/2019 3/24/2019 3/31/2019 4/7/2019
0 0(80CS) 0(80CS) 0(80CS) 0(80CS) 0(80CS)
1 0(50CS) 0(50CS) 0(50CS) 0(50CS) 0(50CS)
2 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS)
3 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS)
4 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS)
5 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS)
6 15(25CS) 15(25CS) 15(25CS) 20(20CS) 20(20CS)
7 12(28CS) 12(28CS) 12(28CS) 12(28CS) 12(28CS)
8 10(30CS) 10(30CS) 10(30CS) 10(30CS) 10(30CS)
9 0(40CS) 0(40CS) 0(40CS) 0(40CS) 0(40CS)
avail_col = ['1/20/2019',
'1/27/2019', '2/3/2019', '2/10/2019', '2/17/2019', '2/24/2019',
'3/3/2019', '3/10/2019', '3/17/2019', '3/24/2019', '3/31/2019',
'4/7/2019']
##changing the data type of selected columns
for i in avail_col:
avail_dat[i] = avail_dat[i].astype(str).apply(lambda x: x.split('(')[0])
avail_dat[i] = avail_dat[i].str.replace('-','0')
avail_dat[i] = avail_dat[i].astype(float)
or_str = ''
for i in avail_col:
or_str = "(avail_dat['"+i+"'] >= 24) | "
print(or_str)
顯然我無法將變量傳遞到數據框進行過濾,或者我還不知道該怎么做,所以我將打印的語句復制粘貼到以下代碼中以過濾數據框
avail_dat = avail_dat[(avail_dat['1/20/2019'] >= 24) |
(avail_dat['1/27/2019'] >= 24) |
(avail_dat['2/3/2019'] >= 24) |
(avail_dat['2/10/2019'] >= 24) |
(avail_dat['2/17/2019'] >= 24) |
(avail_dat['2/24/2019'] >= 24) |
(avail_dat['3/3/2019'] >= 24) |
(avail_dat['3/10/2019'] >= 24) |
(avail_dat['3/17/2019'] >= 24) |
(avail_dat['3/24/2019'] >= 24) |
(avail_dat['3/31/2019'] >= 24) |
(avail_dat['4/7/2019'] >= 24)
]
有沒有一種方法可以傳遞變量而不是每次都復制粘貼?
為此,您可以分別執行每個過濾器,然后再合並它們。 像這樣:
import numpy as np
# add all your boolean series to a list
all_masks = []
for col in avail_col:
condition = (avail_dat[col] >= 24)
all_masks.append(condition)
# use numpy to select the rows where any record evaluates to True
mask = np.array(all_masks).any(axis=0)
avail_dat.loc[mask]
哇。 這里有很多事情要考慮。
首先,我認為您可以通過選擇列來做得更好。 例如,您可以執行以下操作來生成所需的列的列表(因為您說它們以7天為增量):
columns_you_want = list(pd.date_range(start='1/20/2019',freq=pd.DateOffset(days=7),end='4/7/2019').strftime('%m/%d/%Y'))
然后,您可以執行以下操作:
df_avail = df.filter(columns_you_want)
最后,類似:
df_avail[df_avail>24].dropna(how='any',axis=0)
似乎就是您想要的,盡管我不確定最后一步,因為您沒有提供任何所需的輸出。
如果我理解正確,則您正在比較括號前的數字並忽略減號。 如果是這樣,您可以嘗試轉置數據框,然后應用提取功能,或者可以像您編寫的那樣使用split函數,如果實際上有小數,則可能會更好:
dft = df.transpose()
for col in dft.columns:
dft[col] = dft[col].str.extract(r'-?([0-9]+)\(.*').astype(float)
mask = dft >= 24
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.