#python #pandas #dataframe
Вопрос:
У меня есть фрейм данных с более чем 50 000 строками.
Я пытаюсь перебирать строки до первой пустой ячейки, а затем копировать значение идентификатора только в том случае, если par существует. К сожалению, это не работает.
Другими словами, то, что я хочу сделать, — это заменить par значением столбца 1 (id_1, id_2, id_3) на столбец 3 соответственно. Результат будет примерно таким :
Любая идея или помощь будут оценены по достоинству. Заранее всем вам спасибо !
Комментарии:
1.
np.where(df['Column3'] == 'par', df['Column1'], np.nan)
?2. @It_is_Chris это не поможет, np.где нельзя использовать таким образом. Посмотрите на значения в столбце 1.
Ответ №1:
Вы можете использовать .where()
и ffill()
для заполнения каждой группы одинаковыми id
id
значениями в каждой строке Column1
. Затем измените Column3
значения с par
на эти id
значения в той же строке , используя .mask()
, как показано ниже:
Col1_id = df['Column1'].where(df['Column1'].str.startswith('id_')).ffill()
df['Column3'] = df['Column3'].mask(df['Column3'] == 'par', Col1_id)
Результат:
print(df)
Column1 Column2 Column3
0 id_1 NaN NaN
1 n="1" whose id_1
2 n="2" theirs id_1
3 n="3" am id_1
4 NaN NaN NaN
5 id_2 NaN NaN
6 n="4" in id_2
7 n="5" out id_2
8 NaN NaN NaN
9 id_3 NaN NaN
10 n="6" in id_3
11 n="7" out id_3
Комментарии:
1. @Artemis Возможно ли, что в столбце 3 будут значения, отличные от
par
иNaN
? Если да, то будьте осторожны, что решение Аркадиуша может повысить их ценностьNaN
, в то время как мое решение должно хорошо работать с этим.2. Я добавил комментарий к своему ответу с объяснением того, что можно сделать в такой ситуации. Из сообщения с вопросом мы можем заключить, что в колонке 3 есть » par » и «nan». Если есть что — то большее-тогда это решение пользователя. Он может решить, лучше ли поместить туда » нан » или оставить существующее значение.
3. @SeaBean большое вам спасибо за разъяснение. К счастью, он содержит только par и NaN, но спасибо за объяснение, я бы этого не сделал.
Ответ №2:
- Разделите фрейм данных на пустые строки с помощью
numpy.split
. - Если «par» находится в столбце 3, замените все «par» в столбце 3 первым ненулевым значением из «Столбца 1», используя
str.replace
- Добавьте измененный «фрагмент» к выходным данным.
Решение:
import numpy as np
output = pd.DataFrame()
for chunk in np.split(df, df[df.isnull().all(1)].index):
if "par" in chunk["Column3"].tolist():
chunk["Column3"] = chunk["Column3"].str.replace("par", chunk["Column1"].dropna().iat[0])
output = output.append(chunk)
>>> output
Column1 Column2 Column3
0 id_1 None None
1 n="1" whose id_1
2 n="2" theirs id_1
3 n="3" am id_1
4 None None None
5 id_2 None None
6 n="4" in id_2
7 n="5" out id_2
8 None None None
9 id_3 None None
10 n="6" in id_3
11 n="7" out id_3
Комментарии:
1. Спасибо вам за подробный ответ. По соображениям простоты я не использовал точный формат моего df (огромная ошибка, приношу свои извинения). df начинается с 3 дополнительных строк и не заканчивается на par. 1-я строка: все столбцы пусты 2-я : столбец 1 : <название>, столбец 2 и столбец 3: пусто 3-я: все столбцы пусты и заканчиваются столбцом 1: <название></название></название></конец>, столбец 2 и столбец 3: пусто
2. Форматирование полностью теряется в комментариях, поэтому я не понимаю, что вы имеете в виду. Не могли бы вы обновить свой вопрос, чтобы объяснить, в чем проблема?
3. Я проверил ваш код так, как если бы фрейм данных начинался непосредственно со строки id_1, а столбец 3 заканчивался на par, и это работает. Это была моя вина, что я с самого начала не предоставил правильный формат. Еще раз спасибо вам!
Ответ №3:
Ты мог бы поступить так же:
import numpy as np
df['Column3'] = np.where(df['Column3'].eq('par'),
df['Column1'].where(df['Column1'].str.contains('id')).ffill(),
np.nan)
Выход:
Column1 Column2 Column3
0 id_1 NaN NaN
1 n="1" whose id_1
2 n="2" theirs id_1
3 n="3" am id_1
4 id_2 NaN NaN
5 n="4" in id_2
6 n="5" out id_2
7 id_3 NaN NaN
8 n="6" in id_3
9 n="7" out id_3
Редактировать:
Если в столбце 3 также есть другие значения, кроме «par», вы можете поместить df [«Столбец 3″] вместо np.nan в конце функции. Это ваше решение, хотите ли вы поместить » nan «в этот столбец для значений, отличных от «par», или оставить значения, которые там уже существуют.