如何根据pandas数据帧中的多个条件进行子集化

时间:2018-01-12 09:31:12

标签: python pandas subset

我有数据device_class如下:

Base    G   Pref    Sier    Val Other   latest_class    d_id
0       2   0       0       12  0       Val             38
12      0   0       0       0   0       Base            39
0       0   12      0       0   0       Pref            40
0       0   0       12      0   0       Sier            41
0       0   0       12      0   0       Sier            42
12      0   0       0       0   0       Base            43
0       0   0       0       0   12      Other           45
0       0   0       0       0   12      Other           46
0       12  0       0       0   0       G               47
0       0   12      0       0   0       Pref            48
0       0   0       0       0   12      Other           51
0       0   8       5       0   0       Sier            53
0       0   0       0       12  0       Val             54
0       0   0       0       12  0       Val             55

我想只选择设备所在的行(或设备): 1.已连续3个月最近上课 2.我需要过滤掉latest_class ='Other'的记录。 3.现在上面的数据是一年的数据,对于像(38)这样的设备,有两个类,设备已经成为G和Val的一部分。我需要过滤掉这些类型的设备。

所以预期的输出将是:

Base    G   Pref    Sier    Val Other   latest_class    d_id
12      0   0       0       0   0       Base            39
0       0   12      0       0   0       Pref            40
0       0   0       12      0   0       Sier            41
0       0   0       12      0   0       Sier            42
12      0   0       0       0   0       Base            43
0       12  0       0       0   0       G               47
0       0   12      0       0   0       Pref            48
0       0   0       0       12  0       Val             54
0       0   0       0       12  0       Val             55

我已完成以下操作,仅获取其latest_class值大于3的记录:

i = np.arange(len(device_class))
j = (device_class.columns[:-1].values[:, None] == device_class.latest_class.values).argmax(0)
device_class_latest = device_class.iloc[np.flatnonzero(device_class.values[i,j] >= 3)]

有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:1)

我不太确定我是否正确理解了您的数据结构。我假设前6列中的值是某人在课堂上的月数?如果是这样,请尝试以下解决方案:

import pandas as pd

data = {
    'Base': [0, 12, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0],
    'G': [2, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0 ,0],
    'Pref': [0, 0, 12, 0, 0, 0, 0, 0, 0, 12, 0, 8, 0, 0],
    'Sier': [0, 0, 0, 12, 12, 0, 0, 0, 0, 0, 0, 5, 0, 0],
    'Val': [12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12],
    'Other': [0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 12, 0, 0 ,0],
    'latest_class': [
        'Val', 'Base', 'Pref', 'Sier', 'Sier', 'Base', 'Other', 'Other', 'G',
        'Pref', 'Other', 'Sier', 'Val','Val'
    ],
    'd_id': [38, 39, 40, 41, 42, 45, 45, 46, 47, 48, 51, 53, 54, 55]
}

# Load data into DataFrame
df = pd.DataFrame(data)

# Remove records where latest class is Other
df = df[df['latest_class'] != 'Other']

# Filter out records with > 1 class
months_df = df.drop(['latest_class', 'd_id'], axis=1)
months_multiple = months_df[months_df > 0].count(axis=1)
months_1_only = months_multiple == 1
df = df.loc[months_1_only, :]

# Get records where months of latest_class >= 3
rows_to_keep = []
for index, row in df.iterrows():
    latest_class = row['latest_class']
    months_spent = row[latest_class]
    gte_3 = True if months_spent >= 3 else False
    rows_to_keep.append(gte_3)
df = df.iloc[rows_to_keep, :]

# Get them back in the original order (if needed)
df = df[['Base', 'G', 'Pref', 'Sier', 'Val', 'Other', 'latest_class', 'd_id']]
print(df)

输出是您想要的:

    Base   G  Pref  Sier  Val  Other latest_class  d_id
1     12   0     0     0    0      0         Base    39
2      0   0    12     0    0      0         Pref    40
3      0   0     0    12    0      0         Sier    41
4      0   0     0    12    0      0         Sier    42
5     12   0     0     0    0      0         Base    45
8      0  12     0     0    0      0            G    47
9      0   0    12     0    0      0         Pref    48
12     0   0     0     0   12      0          Val    54
13     0   0     0     0   12      0          Val    55

请注意,为了清楚地识别每个步骤,我一直过于冗长,但您可以将很多这些线组合在一起以创建更简洁的脚本。

此外,最终过滤器可以定义为函数,并使用Pandas apply方法而不是iterrows进行应用。