Как исправить потерю индекса при использовании append внутри вложенного цикла for - PullRequest
0 голосов
/ 15 февраля 2019

Я хочу отфильтровать строки из кадра данных, которые ниже порога (5-й процентиль) в другом кадре данных

Я попытался сделать вложенный цикл for и добавить вывод, но индекс потерян, а время выполнения равноочень долго, более двух минут

У меня есть фрейм данных с именем fiveperc в формате (366,1):

    tmin
1   11.32
2   11.0
3   11.41
4   11.885
5   12.155
....
366 13.08

и еще один фрейм данных с именем df2 в формате (18910,1))

date    tmin
1966-01-01  13.9
1966-01-02  17.1
1966-01-03  17.1
1966-01-04  16.2
.....
2018-12-31  17

Использование:

anomaly = []
for yearday,perc in fiveperc.iterrows():
    for date,temp in df2.iterrows():
        if yearday == date.dayofyear:
            anomaly.append(temp - perc)
anomaly = pd.DataFrame(anomaly) 

Использование первого блока кода выше имеет выходной кадр данных (18910,1):

index   tmin
0   2.58
1   3.27
2   4.27
3   2.08
4   -3.52
....
18909   5.579

Проблема здесьв том, что индекс datetime из df2 потерян, что приводит к другому расположению!и что этот вложенный цикл for выполняется более двух минут.

дополнительный код, если я получаю приведенный выше код:

anomaly[anomaly>0]=np.nan
anomaly[anomaly<0]= 1 
anomaly.replace(0, np.nan, inplace=True)
Frequency = pd.DataFrame(final.groupby(lambda x: x.dayofyear)['anomaly'].agg(sum))

Есть ли намного лучший способ сделать это?

1 Ответ

0 голосов
/ 15 февраля 2019

Вы можете посмотреть дневной год по столбцу с помощью аксессора dt:

In [11]: df
Out[11]:
        date  tmin
0 1966-01-01  13.9
1 1966-01-02  17.1
2 1966-01-03  17.1
3 1966-01-04  16.2

In [12]: df1
Out[12]:
     tmin
1  11.320
2  11.000
3  11.410
4  11.885
5  12.155

In [13]: df1.loc[df.date.dt.dayofyear, "tmin"]
Out[13]:
1    11.320
2    11.000
3    11.410
4    11.885
Name: tmin, dtype: float64

In [14]: df["tmin"] - df1.loc[df.date.dt.dayofyear, "tmin"].values
Out[14]:
0    2.580
1    6.100
2    5.690
3    4.315
Name: tmin, dtype: float64

Вы также можете сделать это с групповым преобразованием, но я подозреваю, что это будет немного медленнее:

In [21]: df.groupby(df.date.dt.dayofyear)["tmin"].transform(lambda x: x - df1.loc[x.name, "tmin"])
Out[21]:
0    2.580
1    6.100
2    5.690
3    4.315
Name: tmin, dtype: float64
...