熊猫:根据年份对数据框应用不同的过滤器

时间:2017-12-01 02:13:33

标签: python pandas dataframe data-analysis

如果年份高于或低于某个范围,我想对我的数据框应用不同的过滤器。这是数据框

this.$emit

以下是我编写的产生错误的代码:

v-on

错误是

dataset=pd.DataFrame({'ID': [1,1,1,2,2,2,3,3,3,4,4,4,5,5,5], 
                      'Avail' : [2017,2017,2017,2018,2018,2018,2017,2017,2017,2017,2017,2017,2017,2018,2018], 
                      'Change' : [0,0,2018,0,0,0,0,0,0,0,0,0,2018,0,0],
                      'Pref' : [1,2,3,1,2,3,1,2,3,1,2,3,1,2,3],
                      'Status': ['null', 'null','Q','null','null','null','Q','null','null','null','null','null','Q','null','null']
                      },columns=['ID', 'Avail', 'Change', 'Pref', 'Status'])

我想表现的是:

def yearfilt(x):
    if x.loc[:, ['Avail', 'Change']].values.max(axis=1) < 2018:
        if pd.isnull(x.Status):
            x.drop_duplicates(subset=['STU_ID','Status' ], keep='last')
        else:
            x=x.drop(x[pd.isnull(x.Status)].index)
    else:
        if pd.isnull(x.ASSESSMENT_OUTCOME_CD):
            x.drop_duplicates(subset=['STU_ID','Status' ], keep='first')
        else:
         x=x.drop(x[pd.isnull(x.Status)].index)

df=dataset.groupby(['ID']).apply(yearfilt).sort_values(["ID"]).reset_index(drop=True)

输出应如下所示:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

基本上,从每个ID我只想保留一个。 谢谢

1 个答案:

答案 0 :(得分:1)

您看到的ValueError是因为您正在尝试检查if(some_series)。我不确定哪一行给出了您指出的错误,但看起来您的任何if语句都可能导致此问题。

例如,第一个if语句将一系列值与单个值进行比较。结果是一系列布尔值,而不是if语句可以理解的单个True / False。 pd.isnull可能会出现同样的情况。

您应该检查哪些命令给出了数组结果,并考虑它如何与代码逻辑相符。

如果我能正确理解你的问题,这是一个可能的解决方案:

def yearfilt(group):
    # Apply .max() twice to get a single value across the group.
    # Otherwise the results is a Series, and using if will result in a ValueError.
    if group[['Avail', 'Change']].max().max() < 2018:
        # Returns true if there is a unique status value.
        if group['Status'].unique().shape[0] == 1:
            # Return last row as a dataframe.
            return group.iloc[-1:]
        else:
            # Return ALL rows with status not null (may be more than 1?).
            return group[group['Status'] != 'null']
    else:
        if group['Status'].unique().shape[0] == 1:
            # Return first row as a dataframe.
            return group.iloc[:1]
        else:
            return group[group['Status'] != 'null']

dataset.groupby('ID').apply(yearfilt).reset_index(drop=True)

要记住的事情:

  • 传递给groupby().apply中使用的函数的每个参数都传递给整个数据帧的子集。您需要返回新对象,而不是修改您的功能所接收的组。
  • 如果您使用的是isnull,则您尝试过滤的值必须为None,而不是字符串'null''None''nan'等。有关缺失的值,请参阅the docs
  • 您无法在if上使用Series语句,只能使用一个值。