Я хочу заменить значения в столбцах от P1-6
до P1-95
значениями из столбца family
, если значение в определенном столбце > 0. Вот часть моего входного df te_matrix
:
family P1-6 P1-12 P1-22 P1-25 P1-26 P1-28 P1-88 P1-89 P1-90 P1-92 P1-93 P1-95
Tourist|20 0.712 0.587 0.838 0.675 0.771 0.952 0.746 0.678 0.603 0.728 0.680 0.759
Stowaway|36 0.740 0.809 0.796 0.699 1.000 0.865 0.814 0.888 0.705 0.758 0.759 0.866
Stowaway|4 0.000 0.000 0.000 0.000 0.000 0.000 0.880 0.000 0.000 0.000 0.000 0.000
Я пишу это для одной колонки, P1-6
:
te_matrix['P1-6'] = te_matrix.apply(lambda row: row['family'] if row['P1-6'] > 0 else row['P1-6'], axis=1)
и работает хорошо:
family P1-6 P1-12 P1-22 P1-25 P1-26 P1-28 P1-88 P1-89 P1-90 P1-92 P1-93 P1-95
Tourist|20 Tourist|20 0.587 0.838 0.675 0.771 0.952 0.746 0.678 0.603 0.728 0.680 0.759
Stowaway|36 Stowaway|36 0.809 0.796 0.699 1.000 0.865 0.814 0.888 0.705 0.758 0.759 0.866
Stowaway|4 0.000 0.000 0.000 0.000 0.000 0.000 0.880 0.000 0.000 0.000 0.000 0.000
но как использовать его для всех нужных столбцов, не прописывая построчно почти один и тот же код?
Думаю начать с:
cols = te_matrix.filter(like='P1-').columns
но как применить это к предыдущему коду?
@mozway Я только что отредактировал, чтобы исправить выравнивание, ты этого хотел? Или 0.000
в результате P1-6
должно быть 0.0
, если это число с плавающей запятой, а столбец является объектом?
@wjandrea, спасибо, действительно было бы важно, чтобы OP предоставил этот вывод, чтобы знать типы данных
Я думаю, вы на правильном пути, используя cols = te_matrix.filter(like='P1-').columns
. После этого примените условие к каждому указанному столбцу.
Код:
for col in cols:
te_matrix[col] = te_matrix.apply(lambda row: row['family'] if row[col] > 0 else row[col], axis=1)
Выход:
family P1-6 P1-12 P1-22 P1-25 \
0 Tourist|20 Tourist|20 Tourist|20 Tourist|20 Tourist|20
1 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36
2 Stowaway|4 0.0 0.0 0.0 0.0
P1-26 P1-28 P1-88 P1-89 P1-90 \
0 Tourist|20 Tourist|20 Tourist|20 Tourist|20 Tourist|20
1 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36
2 0.0 0.0 Stowaway|4 0.0 0.0
P1-92 P1-93 P1-95
0 Tourist|20 Tourist|20 Tourist|20
1 Stowaway|36 Stowaway|36 Stowaway|36
2 0.0 0.0 0.0
Это вызвало у меня ошибку TypeError: File "/home/emoranska/Pulpit/burak/P1_P4/calculations.py", line 30, in <lambda> te_matrix[col] = te_matrix.apply(lambda row: row['family'] if row[col] > 0 else row[col], axis=1) TypeError: '>' not supported between instances of 'str' and 'int'
Пробовали te_matrix[cols] = te_matrix[cols].astype(float)
?
Да, такая же ошибка вылезла..
@emor Вам нужно отменить .apply()
, прежде чем запускать этот код. Ваш код меняет dtype P1-6
с числового на object
(что, кстати, довольно странно).
@wjandrea, я проверил, как ты написал, и это действительно странно.. Почему это так работает?
@emor О, я имею в виду, странно, что вы меняете типы столбцов. Зачем ты это делаешь?
Не используйте apply
, он здесь не нужен, это действительно неэффективно.
Используйте логическое индексирование:
df.loc[df['P1-6'].gt(0), 'P1-6'] = df['family']
Выход:
family P1-6 P1-12 P1-22 P1-25 P1-26 P1-28 P1-88 P1-89 P1-90 P1-92 P1-93 P1-95
0 Tourist|20 Tourist|20 0.587 0.838 0.675 0.771 0.952 0.746 0.678 0.603 0.728 0.680 0.759
1 Stowaway|36 Stowaway|36 0.809 0.796 0.699 1.000 0.865 0.814 0.888 0.705 0.758 0.759 0.866
2 Stowaway|4 0.0 0.000 0.000 0.000 0.000 0.000 0.880 0.000 0.000 0.000 0.000 0.000
Если вы хотите обновить несколько столбцов одновременно, используйте маску :
cols = df.filter(like='P1-').columns
df[cols] = df[cols].mask(df[cols].gt(0), df['family'], axis=0)
Или, если вы не уверены, содержат ли входные столбцы только числа, с помощью pd.to_numeric:
cols = df.filter(like='P1-').columns
df[cols] = df[cols].mask(df[cols].apply(pd.to_numeric, errors='coerce').gt(0),
df['family'], axis=0)
Выход:
family P1-6 P1-12 P1-22 P1-25 P1-26 P1-28 P1-88 P1-89 P1-90 P1-92 P1-93 P1-95
0 Tourist|20 Tourist|20 Tourist|20 Tourist|20 Tourist|20 Tourist|20 Tourist|20 Tourist|20 Tourist|20 Tourist|20 Tourist|20 Tourist|20 Tourist|20
1 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36 Stowaway|36
2 Stowaway|4 0.0 0.0 0.0 0.0 0.0 0.0 Stowaway|4 0.0 0.0 0.0 0.0 0.0
Другой способ сделать
cols = te_matrix.filter(like='P1-').columns
возможно
for col in te_matrix.columns:
if col.startswith("P1-"):
do_something()
Можете ли вы отредактировать свой вопрос, чтобы предоставить результат
te_matrix.to_dict('tight')
для воспроизводимости?