Добавление недостающих строк панд DataFrame, когда индекс содержит повторяющиеся данные - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть DataFrame с dtype=object как:

          YY    MM  DD  hh  var1    var2
.
.
.

10512   2013    01  01  06  1.64    4.64
10513   2013    01  01  07  1.57    4.63
10514   2013    01  01  08  1.56    4.71
10515   2013    01  01  09  1.45    4.69
10516   2013    01  01  10  1.53    4.67
10517   2013    01  01  11  1.31    4.63
10518   2013    01  01  12  1.41    4.70
10519   2013    01  01  13  1.49    4.80
10520   2013    01  01  20  1.15    4.91
10521   2013    01  01  21  1.14    4.74
10522   2013    01  01  22  1.10    4.95

Как видно, отсутствуют строки, соответствующие часам (hh) (например, между 10519 и 10520 строками, hh скачет с 13 до 20). Я попытался добавить пробел, установив hh в качестве индекса, как это обсуждалось здесь: Отсутствующие данные, вставьте строки в Pandas и заполните NAN

df=df.set_index('hh')
new_index = pd.Index(np.arange(0,24), name="hh")
df=df.reindex(new_index).reset_index() 

и достигните чего-то вроде:

          YY    MM  DD  hh  var1    var2

10519   2013    01  01  13  1.49    4.80
10520   2013    01  01  14  Nan     Nan
10521   2013    01  01  15  Nan     Nan
10522   2013    01  01  16  Nan     Nan
...
10523   2013    01  01  20  1.15    4.91
10524   2013    01  01  21  1.14    4.74
10525   2013    01  01  22  1.10    4.95

Но я сталкиваюсь с ошибкой "cannot reindex from a duplicate axis" для части df=df.reindex(new_index). Для каждого hh=0,1,...,23 есть повторяющиеся значения, поскольку одно и то же значение hh будет повторяться для разных месяцев (MM) и лет (YY). Вероятно, в этом причина. Как я могу решить проблему?

В общем, как можно заполнить недостающие строки панд DataFrame, когда индекс содержит дубликаты данных. Я ценю любые комментарии.

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Этот код делает именно то, что вам нужно.

import pandas as pd
import numpy as np
from io import StringIO

YY, MM, DD, hh, var1, var2 = [],[],[],[],[],[]


a = '''10512   2013    01  01  06  1.64    4.64
10513   2013    01  01  07  1.57    4.63
10514   2013    01  01  08  1.56    4.71
10515   2013    01  01  09  1.45    4.69
10516   2013    01  01  10  1.53    4.67
10517   2013    01  01  11  1.31    4.63
10518   2013    01  01  12  1.41    4.70
10519   2013    01  01  13  1.49    4.80
10520   2013    01  01  20  1.15    4.91
10521   2013    01  01  21  1.14    4.74
10522   2013    01  01  22  1.10    4.95
10523   2013    01  01  27  1.30    4.55
10524   2013    01  01  28  1.2     4.62
'''

text = StringIO(a)

for line in text.readlines():
    a = line.strip().split(" ")
    a = list(filter(None, a))
    YY.append(a[1])
    MM.append(a[2])
    DD.append(a[3])
    hh.append(a[4])
    var1.append(a[5])
    var2.append(a[6])

df = pd.DataFrame({'YY':YY, 'MM':MM, 'DD':DD,
                   'hh':hh, 'var1':var1, 'var2':var2})

df['hh'] = df.hh.astype(int)


a = np.diff(df.hh)
b = np.where(a!=1)


df2 = df.copy(deep=True)

for i in range(len(df)):

    if (i in b[0]):
        line = pd.DataFrame(columns=['YY', 'MM', 'DD',
                                     'hh', 'var1', 'var2'])
        for k in range(a[i]-1):

            line.loc[k]=[df2.iloc[i, 0], df2.iloc[i, 1],
                         df2.iloc[i, 2], df2.iloc[i, 3]+k+1 ,
                         np.nan, np.nan]

        df = pd.concat([df.loc[:i], 
                line, df.loc[i+1:]])


df.reset_index(inplace=True, drop=True)

print(df)

      YY  MM  DD  hh  var1  var2
0   2013  01  01   6  1.64  4.64
1   2013  01  01   7  1.57  4.63
2   2013  01  01   8  1.56  4.71
3   2013  01  01   9  1.45  4.69
4   2013  01  01  10  1.53  4.67
5   2013  01  01  11  1.31  4.63
6   2013  01  01  12  1.41  4.70
7   2013  01  01  13  1.49  4.80
8   2013  01  01  14   NaN   NaN
9   2013  01  01  15   NaN   NaN
10  2013  01  01  16   NaN   NaN
11  2013  01  01  17   NaN   NaN
12  2013  01  01  18   NaN   NaN
13  2013  01  01  19   NaN   NaN
14  2013  01  01  20  1.15  4.91
15  2013  01  01  21  1.14  4.74
16  2013  01  01  22  1.10  4.95
17  2013  01  01  23   NaN   NaN
18  2013  01  01  24   NaN   NaN
19  2013  01  01  25   NaN   NaN
20  2013  01  01  26   NaN   NaN
21  2013  01  01  27  1.30  4.55
22  2013  01  01  28   1.2  4.62
0 голосов
/ 18 сентября 2018

Сначала создайте новый столбец с указанием времени, включая дату и час, типа datetime. Это можно сделать следующим образом:

df = df.rename(columns={'YY': 'year', 'MM': 'month', 'DD': 'day', 'hh': 'hour'})
df['time'] = pd.to_datetime(df[['year', 'month', 'day', 'hour']])

Чтобы использовать to_datetime таким образом, имена столбцов должны быть year, month, day и hour, поэтому используется rename.

Чтобы получить ожидаемый результат, установите этот новый столбец в качестве индекса и используйте resample:

df.set_index('time').resample('H').mean()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...