首页 > 解决方案 > 在熊猫数据框中,计算一个条件在一列中出现的次数?

问题描述

背景

我有五年的 NO2 测量数据,在 csv 文件中 - 每个位置和年份都有一个文件。我已将所有文件以相同格式加载到 pandas 数据框中:

Date    Hour    Location    NO2_Level
0   01/01/2016  00  Street  18
1   01/01/2016  01  Street  39
2   01/01/2016  02  Street  129
3   01/01/2016  03  Street  76
4   01/01/2016  04  Street  40

目标

对于每个数据帧计数,NO2_Level 大于 150 的次数并输出。

所以我写了一个循环,从正确的目录创建所有数据帧并适当地清理它们。

问题

无论我尝试过什么都会产生我在检查时知道的结果是不正确的,例如: - 给定年份每个位置的计数值是相同的(可能但不太可能) - 对于我知道应该有任何正数的一年计数,每个位置返回 0

我试过的

我已经尝试了很多方法来为每个数据框获取这个值,例如使列成为一个系列:

NO2_Level = pd.Series(df['NO2_Level'])
count = (NO2_Level > 150).sum()'''

使用 pd.count():

count = df[df['NO2_Level'] >= 150].count()

这两种方法最接近我想要输出的内容

测试示例

data = {'Date': ['01/01/2016','01/02/2016',' 01/03/2016', '01/04/2016', '01/05/2016'], 'Hour': ['00', '01', '02', '03', '04'], 'Location':  ['Street','Street','Street','Street','Street',], 'NO2_Level': [18, 39, 129, 76, 40]}
df = pd.DataFrame(data=d)
NO2_Level = pd.Series(df['NO2_Level'])
count = (NO2_Level > 150).sum()
count

预期产出

因此,从这里我试图让它为每个数据帧输出一行,格式为位置、年份、计数(条件):

Kirkstall Road,2013,47
Haslewood Close,2013,97
...
Jack Lane Hunslet,2015,158

所以上面的例子会产生

Street, 2016, 1

实际 每年对每个位置产生相同的结果,对于某些年份(2014 年),在检查时计数似乎根本不起作用应该有:

Kirkstall Road,2013,47
Haslewood Close,2013,47
Tilbury Terrace,2013,47
Corn Exchange,2013,47
Temple Newsam,2014,0
Queen Street Morley,2014,0
Corn Exchange,2014,0
Tilbury Terrace,2014,0
Haslewood Close,2015,43
Tilbury Terrace,2015,43
Corn Exchange,2015,43
Jack Lane Hunslet,2015,43
Norman Rows,2015,43

标签: pythonpandasdataframe

解决方案


这是一个(随机)生成样本的解决方案:

def random_dates(start, end, n):
    start_u = start.value // 10 ** 9
    end_u = end.value // 10 ** 9
    return pd.to_datetime(np.random.randint(start_u, end_u, n), unit='s')

location = ['street', 'avenue', 'road', 'town', 'campaign']

df = pd.DataFrame({'Date' : random_dates(pd.to_datetime('2015-01-01'), pd.to_datetime('2018-12-31'), 20),
                   'Location' : np.random.choice(location, 20),
                   'NOE_level' : np.random.randint(low=130, high= 200, size=20)})

#Keep only year for Date
df['Date'] = df['Date'].dt.strftime("%Y")

print(df)

df = df.groupby(['Location', 'Date'])['NOE_level'].apply(lambda x: (x>150).sum()).reset_index(name='count')
print(df)

示例 df 生成:

        Date  Location  NOE_level
0       2018      town        191
1       2017  campaign        187
2       2017      town        137
3       2016    avenue        148
4       2017  campaign        195
5       2018      town        181
6       2018      road        187
7       2018      town        184
8       2016      town        155
9       2016    street        183
10      2018      road        136
11      2017      road        171
12      2018    street        165
13      2015    avenue        193
14      2016  campaign        170
15      2016    street        132
16      2016  campaign        165
17      2015      road        161
18      2018      road        161
19      2015      road        140 

输出:

    Location       Date  count
0     avenue       2015      1
1     avenue       2016      0
2   campaign       2016      2
3   campaign       2017      2
4       road       2015      1
5       road       2017      1
6       road       2018      2
7     street       2016      1
8     street       2018      1
9       town       2016      1
10      town       2017      0
11      town       2018      3

推荐阅读