Как вы кратко складываете две серии вместе, но только добавляете положительные значения? - PullRequest
0 голосов
/ 21 сентября 2018

у меня две серии;

energy_dict['QLD'] = 

Timestamp
2017-04-27 00:00:00    523.720765
2017-04-27 01:00:00    512.180608
2017-04-27 02:00:00    519.076642
2017-04-27 03:00:00    516.329201
2017-04-27 04:00:00    525.150158
   ...                 ...
Freq: H, Name: QLD Total Energy (MWh), Length: 8760, dtype: float64

и

Incoming_Flow = 

Timestamp
2017-04-27 00:00:00    -8.961111
2017-04-27 01:00:00     9.503472
2017-04-27 02:00:00   -10.776389
2017-04-27 03:00:00     1.451389
2017-04-27 04:00:00   -10.388195
        ...               ...

Частота: H, Имя: METEREDMWFLOW NQ-MNSP1, Длина: 8760, dtype: float64

Я хотел бы добавить их вместе, но только когда второй больше нуля.Каков наилучший способ сделать это?

Я знаю, что мог бы сделать что-то подобное;

Incoming_Flow[Incoming_Flow < 0 ] = 0

но я бы хотел сделать все это в одну строку

Ответы [ 3 ]

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

Вы также можете использовать Series.add и Series.where:

s = energy_dict['QLD'].add(Incoming_Flow.where(Incoming_Flow.gt(0), 0))

Это также на ~ 18% быстрее, чем решение mask, еслипроизводительность важна:

[пруф]

s1 = pd.Series(np.arange(50000))
s2 = pd.Series(np.random.randint(-4, 10,50000))

%timeit s1.add(s2.mask(s2 < 0, 0), fill_value=0)
1.17 ms ± 25.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit s1.add(s2[s2 > 0], fill_value=0)
4.68 ms ± 289 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit s1.add(s2.where(s2.gt(0), 0))
988 µs ± 50.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
0 голосов
/ 21 сентября 2018

Быстрее, используя numpy add и где

import numpy as np

qld = [523.720765, 512.180608, 519.076642, 516.329201, 525.150158]
flow = [ -8.961111,   9.503472, -10.776389,   1.451389, -10.388195]

df1 = pd.DataFrame(qld, columns=['QLD'])
df2 = pd.DataFrame(flow, columns=['Incoming_Flow'])

s = np.add(df1['QLD'], np.where(df2['Incoming_Flow'] > 0, df2['Incoming_Flow'], 0))

print(s)

0    523.720765
1    521.684080
2    519.076642
3    517.780590
4    525.150158

Сроки:

s1 = pd.Series(np.arange(50000))
s2 = pd.Series(np.random.randint(-4, 10,50000))

%timeit s1.add(s2.where(s2.gt(0), 0))
890 µs ± 58.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit np.add(s1, np.where(s2 > 0, s2, 0))
367 µs ± 6.82 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
0 голосов
/ 21 сентября 2018

Используйте Series.add с Series.mask:

s = energy_dict['QLD'].add(Incoming_Flow.mask(Incoming_Flow < 0, 0), fill_value=0)
print (s)
0    523.720765
1    521.684080
2    519.076642
3    517.780590
4    525.150158
dtype: float64

print (Incoming_Flow.mask(Incoming_Flow < 0, 0))
0    0.000000
1    9.503472
2    0.000000
3    1.451389
4    0.000000
Name: METEREDMWFLOW N-Q-MNSP1, dtype: float64

Или фильтруйте серию и используйте параметр fill_value=0:

fill_value : Нет или значение с плавающей запятой, значение по умолчанию Нет (NaN)

Заполните существующие пропущенные (NaN) значения и любой новый элемент, необходимый для успешного выравнивания рядов, этим значением до вычисления.Если данные в обоих соответствующих местоположениях серии отсутствуют, будет отсутствовать результат

s = energy_dict['QLD'].add(Incoming_Flow[Incoming_Flow > 0], fill_value=0)
print (s)
0    523.720765
1    521.684080
2    519.076642
3    517.780590
4    525.150158
dtype: float64

Сведения :

print (Incoming_Flow[Incoming_Flow > 0])
1    9.503472
3    1.451389
Name: METEREDMWFLOW N-Q-MNSP1, dtype: float64

РЕДАКТИРОВАТЬ:

Если важна производительность, используйте numpy.where:

s = pd.Series(np.where(Incoming_Flow < 0, 0, Incoming_Flow ), index=Incoming_Flow.index)
#if DatetimeIndex values are same in both Series 
s = np.where(Incoming_Flow < 0, 0, Incoming_Flow )
energy_dict['QLD'].add(s, fill_value=0)
...