Заполнение раздела данных по разделам без цикла - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть Dataframe примерно так:

  sync 
0    1
1    1
2    0
3    1
4    0

столбец syn c переключается между 0 и 1. Мне нужно создать новый столбец, который будет заполнен элементом списка на основе Дельта столбца syn c.

Например, список со значениями для заполнения равен [17, 8, 0]

Тогда результирующий Dataframe должен выглядеть следующим образом:

  sync   res
0    1   NaN
1    1    17
2    0     8
3    1     0
4    0    17

Таким образом, в большинстве случаев каждый раз, когда столбец syn c имеет Delta! = 0, следует добавить следующее значение списка. Список следует повторить, если он короче, чем строки кадра данных. Это не так сложно достичь с помощью функции .iterrows() или .itertuples(). Проблема в том, что в фрейме данных обычно 6 миллионов строк, и это занимает некоторое время.

Я читал итерации по строкам кадра данных, что не очень хорошая практика, потому что это медленно. Поэтому мне нужно решение без al oop, но я не могу придумать ни одной функции, которую я могу использовать с df.apply(), которая бы решала проблему.

Вот мое текущее решение: я создал фрейм данных только с этими строк, где syn c имеет Delta! = 0 и повторяется в каждой строке этого кадра данных, но это все еще занимает довольно много времени (около 500 с).

mylist = [17, 4, 9, 3, 76, 4]
listindex = 0

# calculate the difference
diff = data[data["time"] >= starttime].diff()

# get all the rows where the Delta is != 0
edges = diff[diff["sync"] != 0]

old_index = 0

# initiate res column
data['res'] = 0

for index, edge in edges.iterrows():
    if old_index:
        # fill rows from "oldindex" to "index+1" of "res" column with value of "mylist"
        data.at[old_index:index+1, "sync"] = mylist[listindex]
        # increment index if its not the end of the list
        if 0 <= listindex < len(mylist)-1:
            listindex += 1
        else:
            listindex = 0
    # save current index for next iteration
    old_index = index

1 Ответ

0 голосов
/ 25 февраля 2020

Вот решение с np.title:

# data 
df = pd.DataFrame({'sync':[1,1,0,1,0]})
lst = [17,8,0]

# initialization
df['res'] = np.nan

# fill
non_zeros = ~df['sync'].diff(-1).eq(0)
df.loc[non_zeros, 'res'] = np.tile(lst, non_zeros.sum())[:non_zeros.sum()]

Вывод:

   sync   res
0     1   NaN
1     1  17.0
2     0   8.0
3     1   0.0
4     0  17.0

Примечание : Если другие столбцы не относятся к выводу в в любом случае, рассмотрите возможность удаления их из данных примера (как в моем примере).

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