В кадре данных pandas подсчитать, сколько раз условие возникает в одном столбце? - PullRequest
1 голос
/ 23 марта 2019

Справочная информация

У меня есть данные измерений 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

Ожидаемые результаты

Итак, из этого я пытаюсь вывести по одной строке для каждого кадра данных, который был сделан в формате Location, year, count (of condition):

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

Ответы [ 2 ]

1 голос
/ 23 марта 2019

Надеюсь, это поможет.

import pandas as pd

ddict = {
    'Date':['2016-01-01','2016-01-01','2016-01-01','2016-01-01','2016-01-01','2016-01-02',],
    'Hour':['00','01','02','03','04','02'],
    'Location':['Street','Street','Street','Street','Street','Street',],
    'N02_Level':[19,39,129,76,40, 151],
}

df = pd.DataFrame(ddict)

# Convert dates to datetime
df['Date'] = pd.to_datetime(df['Date'])

# Make a Year column
df['Year'] = df['Date'].apply(lambda x: x.strftime('%Y'))

# Group by lcoation and year, count by M02_Level > 150
df1 = df[df['N02_Level'] > 150].groupby(['Location','Year']).size().reset_index(name='Count')

# Interate the results
for i in range(len(df1)):
    loc = df1['Location'][i]
    yr = df1['Year'][i]
    cnt = df1['Count'][i]
    print(f'{loc},{yr},{cnt}')


### To not use f-strings
for i in range(len(df1)):
    print('{loc},{yr},{cnt}'.format(loc=df1['Location'][i], yr=df1['Year'][i], cnt=df1['Count'][i]))

Пример данных:

        Date Hour Location  N02_Level
0 2016-01-01   00   Street         19
1 2016-01-01   01   Street         39
2 2016-01-01   02   Street        129
3 2016-01-01   03   Street         76
4 2016-01-01   04   Street         40
5 2016-01-02   02   Street        151

Вывод:

Street,2016,1
1 голос
/ 23 марта 2019

вот решение с сгенерированным образцом (случайным образом):

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 

output:

    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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...