#python #pandas
#python #pandas
Вопрос:
У меня есть «большая» таблица фреймов данных с индексом, представляющим собой коды стран (альфа-3), а столбцы — годы (с 1900 по 2000), импортированные через pd.read_csv(…) [как я понимаю, на самом деле это строка, поэтому мне нужно передать ее, например, как «1945»].
Значения равны 0,1,2,3. Мне нужно «распространять» эти значения до следующего значения, отличного от 0, для каждой строки.
- пример : 0 0 1 0 0 3 0 0 2 1
- становится: 0 0 1 1 1 3 3 3 2 1
Я понимаю, что мне не следует использовать итерации (текущая реализация примерно такая, как вы можете видеть, использование 2 циклов не является оптимальным, я думаю, я мог бы избавиться от одного, используя apply(row) )
def spread_values(df):
for idx in df.index:
previous_v = 0
for t_year in range(min_year, max_year):
current_v = df.loc[idx, str(t_year)]
if current_v == 0 and previous_v != 0:
df.loc[idx, str(t_year)] = previous_v
else:
previous_v = current_v
Однако мне сказали, что я должен использовать функцию apply () или векторизацию или понимание списка, потому что это не оптимально?
Однако функция apply, независимо от оси, не позволяет динамически получать индекс / столбец (который мне нужен для условного обновления ячейки), и я думаю, что основная проблема, с которой я не могу заставить работать параметры vec или list, заключается в том, что у меня нет конечного набора имен столбцов, нодовольно широкий диапазон (во всех примерах, которые я вижу, используется несколько именованных столбцов …)
Какое здесь было бы более оптимальным / более элегантным решением?
ИЛИ фреймы данных вообще не подходят для моих данных? что я должен использовать вместо этого?
Ответ №1:
Вы можете использовать df.replace(to_replace=0, method='ffil)
. Это заполнит все нули в вашем фрейме данных (за исключением нулей, возникающих в начале вашего фрейма данных) предыдущим ненулевым значением для каждого столбца.
Если вы хотите это сделать, к rowwise
сожалению .replace()
, функция не принимает axis
аргумент. Но вы можете transpose
dataframe
заменить нули и transpose
снова: df.T.replace(0, method='ffill').T
Комментарии:
1. Спасибо, я не знал об этом. Я реализовал его, и, похоже, он заменяет значения по вертикали, а не по горизонтали. pandas.pydata.org/pandas-docs/stable/reference/api / … не показывает параметр для изменения оси?
2. Я вижу, не заметил, что вы намеревались заполнить нули последовательно. Отредактировал свой ответ, чтобы он работал.
3. Я использовал двойное транспонирование, и оно работает 😉 Я только что видел, что вы также предложили это. Спасибо! работает как шарм