使用循环过滤熊猫数据框中的多列

时间:2019-02-11 16:41:30

标签: python pandas dataframe

上下文:我在excel中有一个数据,我们通过熊猫处理该数据以进行清理,然后在ML模型中进一步使用它。在清理过程中,我尝试基于多个列将数据过滤为OR条件。这组列的标题名称是星期几,因此这7列代表7周。该列的标题名称每周更改一次。因此,我无法保持一致的代码来自动选择标题名称。

我尝试过的逻辑:我编写了一个代码块以使用此日期列打印“ OR”条件,然后复制此打印语句粘贴到“数据框索引”部分。下面是它的外观:

我现在正在复制粘贴列。但是我想我可以通过将基于类型的条件应用于列名称来构建一种用于标识日期列的逻辑

样本数据:

16:38
17:08

显然我不能将变量传递到数据框进行过滤,或者我还不知道该怎么做,所以我将打印的语句复制粘贴到以下代码中以过滤数据框

 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)

有没有一种方法可以传递变量而不是每次都复制粘贴?

3 个答案:

答案 0 :(得分:0)

您可以通过分别执行每个过滤器,然后合并它们来实现。像这样:

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]

答案 1 :(得分:0)

哇。这里有很多要考虑的问题。

首先,我认为您可以通过选择列来做得更好。例如,您可以执行以下操作来生成所需的列的列表(因为您说它们以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)

似乎是您想要的,尽管由于您没有提供任何所需的输出,我不确定最后一步。

答案 2 :(得分:0)

如果我正确理解,您正在比较括号前的数字并忽略减号。如果是这样,您可以尝试转置数据框,然后应用提取函数,或者可以像您编写的函数那样使用split函数,如果您实际上有小数,则可能会更好:

dft = df.transpose()
for col in dft.columns:
    dft[col] = dft[col].str.extract(r'-?([0-9]+)\(.*').astype(float)
mask = dft >= 24