Как мне подсчитать количество дней на основе месяцев с нулевыми данными?

#python #pandas

#python #панды

Вопрос:

Я пишу скрипт, в котором я читаю в формате csv с несколькими столбцами и строками. Мне нужно, чтобы скрипт суммировал значения в каждом столбце для одной строки и возвращал, какие столбцы имеют нулевое значение для строки. Вот пример того, как выглядят данные, есть несколько других столбцов, но это столбцы, представляющие интерес для моего вопроса:

     JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
     0   0   5   5   0   5   5   5   5   0   0   0
  

это то, что у меня есть до сих пор:

     import pandas as pd
    import os

    os.chdir('C:\users\vroland\desktop\RR_WMD\WUdata')

    fout=open("WUinput.csv","a")
    #read water use file
    df=pd.read_csv("WUtest.csv")
    #Header amp; months with zero values
    cols=df.columns
    #Boolean array of columns with zero values
    bt=df.apply(lambda x: x==0)
    #List months with zero values
    zar=bt.apply(lambda x:list(cols[x.values]),axis=1)
  

Я пробовал комбинацию способов, включая if операторы, но я продолжаю получать сообщение об ошибке, в котором указано, что мой условный оператор неоднозначен, поэтому я пробую другой маршрут. Итак, это то, что я должен сейчас сделать с приведенным выше блоком кода:

    a=30
   b=31
   c=28
   num_days=pd.DataFrame({'JAN':[b],'FEB':[c],'MAR':[b],'APR':[a],'MAY':[b],
                          'JUN':[a],'JUL':[b],'AUG':[b],'SEP':[a],'OCT':[b],
                          'NOV':[a],'DEC':[b]})
  

Идея состоит в том, чтобы использовать значения, возвращаемые zar для поиска соответствующего значения дня в моем фрейме данных num_days . Верните это значение и вычислите общее количество дней со значением, равным нулю.

Комментарии:

1. «Мне нужен скрипт для суммирования значений в каждом столбце для одной строки» разве это не означает, что вам просто нужно значение в каждом столбце?

2. Да, я хочу значение в каждом столбце, я просто пытался быть как можно более конкретным, я просто не хотел, чтобы это интерпретировалось так, как я хотел суммировать весь столбец, потому что каждая строка является уникальным событием. Итак, я хочу значение в каждом столбце, суммировать ненулевые значения и возвращать. Затем верните столбцы с нулями, чтобы я мог назначить правильное количество дней в зависимости от месяца.

Ответ №1:

ну, я бы избавился от строки «fout». Похоже, вы не записываете в этот файл, и он не обязательно должен быть открыт, чтобы использовать функцию «read_csv» pandas. затем вы можете просмотреть каждую строку и найти, что равно нулю, а что нет

 returnArray = []
i=0
while i < len(df.values):
    j=14 #since user only cares about column 14-26
    while j < len(df.values[i]):
        if df.values[i][j] == 0:
            returnArray.append([i,j])
        j=j 1
    i=i 1
  

Комментарии:

1. Я мог бы прокомментировать эту строку, и должен был, я собираюсь записать все это в другой файл, просто сначала нужно заставить его работать правильно. Так m_entry df.value же, как и at i,j . Мне нужно определить его, чтобы использовать его, не хочет работать как есть, можете ли вы просто int m_entry на python

2. извините, я пересмотрел свой код перед публикацией и не тщательно вычитал. теперь это должно иметь больше смысла

3. Да, понял. Я новичок в pandas и python, если на то пошло, но, используя этот метод, он возвращает нулевые значения для всех 26 столбцов моего df, меня интересуют только последние 12 столбцов. Итак, могу ли я настроить это len так, чтобы смотреть только на столбцы 14-26?

Ответ №2:

Рассмотрим pd.DataFrame df

 cols = ['JAN', 'FEB', 'MAR', 'APR',
        'MAY', 'JUN', 'JUL', 'AUG',
        'SEP', 'OCT', 'NOV', 'DEC']

df = pd.DataFrame(np.random.randint(0, 3, (10, 12)), columns=cols)
df
  

введите описание изображения здесь


Я буду использовать оценку каждой строки row == 0 в качестве логической маски для самих столбцов. Используйте list , чтобы хорошо вписаться в pd.Series

 df.eq(0).apply(lambda x: list(df.columns[x]), 1)

0                   [FEB, MAR, APR, NOV]
1                        [FEB, OCT, NOV]
2              [JAN, APR, AUG, NOV, DEC]
3                        [MAR, APR, SEP]
4                   [MAY, JUN, NOV, DEC]
5                        [APR, AUG, NOV]
6         [MAR, APR, JUN, OCT, NOV, DEC]
7    [JAN, FEB, APR, JUL, OCT, NOV, DEC]
8              [MAY, JUL, AUG, SEP, OCT]
9         [FEB, MAR, APR, JUN, AUG, SEP]
dtype: object
  

Чтобы получить количество дней

 days_in_month = pd.Series(dict(
        JAN=31, FEB=28, MAR=31,
        APR=30, MAY=31, JUN=30,
        JUL=31, AUG=31, SEP=30,
        OCT=31, NOV=30, DEC=31
    ))

df.eq(0).dot(days_in_month)

0    119
1     89
2    153
3     91
4    122
5     91
6    183
7    212
8    154
9    180
dtype: int64
  

Комментарии:

1. Спасибо, это в значительной степени результат, который я получаю zar . Меня действительно интересуют эти лямбда-функции, что было бы хорошим способом вычислить общее количество дней, если я получаю здесь такой тип вывода.

2. Спасибо, вот мой следующий вопрос: как мне манипулировать df.eq(0).dot(days_in_month) , чтобы учесть тот факт, что размеры моей матрицы разные. В моем фрейме данных у меня 26 столбцов, но в этом конкретном вопросе меня интересуют только 15-26.