Существует ли функция pandas / numpy для распределения целого числа по последующим нулям? - PullRequest
3 голосов
/ 03 мая 2019

Я пытаюсь включить, например, следующую строку:

"3, 0, 0, 2, 0, 0, 0, 1, 0" 

в

"1, 1, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5". 

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

Я в основном пользователь R и выполнил это в R с:

x <- c(0,0,3,0,0,2,0,0,0,1,0)

ave(x,cumsum(x))

Мне трудно найти подобный простой поток в Python, существует ли он?

Ответы [ 3 ]

4 голосов
/ 03 мая 2019

к сожалению, в пандах нет таких функций, о которых мне известно, хотя вы можете использовать groupby() для этого:

s="3, 0, 0, 2, 0, 0, 0, 1, 0"
ser=pd.Series(s.split(',')).astype(int)
#this splits the string and converts to a series

Теперь мы разделяем серию на группы (Спасибо @QuangHoang) и берем cumsum() того же самого. Проверьте ниже для вывода cumsum. Затем с помощью группировки мы преобразуем серию в mean

В конце мы добавляем .tolist() и .join() их, так как вы хотели получить вывод в виде строки.

','.join(ser.groupby(ser.cumsum()).transform('mean').astype(str).tolist())
#or ','.join(ser.groupby((ser.ne(0)).cumsum()).transform('mean').astype(str).tolist())

'1.0,1.0,1.0,0.5,0.5,0.5,0.5,0.5,0.5'

Выход для cumsum():

ser.cumsum()

0    3
1    3
2    3
3    5
4    5
5    5
6    5
7    6
8    6
1 голос
/ 03 мая 2019

Данные от anky_91

ser.mask(ser==0).ffill()/ser.groupby(ser.ne(0).cumsum()).transform('count')
Out[1242]: 
0    1.0
1    1.0
2    1.0
3    0.5
4    0.5
5    0.5
6    0.5
7    0.5
8    0.5
dtype: float64
1 голос
/ 03 мая 2019

Вот способ приблизиться к этому, используя numpy:

s = "3, 0, 0, 2, 0, 0, 0, 1, 0" 
a = np.fromstring(s, sep=',')
# array([3., 0., 0., 2., 0., 0., 0., 1., 0.])
# Find the length of consecutive 0s in a
d = np.diff(np.r_[False, a==0, False].astype(int))
zero_len = np.flatnonzero(d==-1) - np.flatnonzero(d==1)
# array([2, 3, 1], dtype=int64)
# normalize the values and repeat as many times as zero_len+1
np.repeat(a[a!=0]/(zero_len+1), zero_len+1)

, что дает:

array([1. , 1. , 1. , 0.5, 0.5, 0.5, 0.5, 0.5, 0.5])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...