Сопоставление строки и столбца с числовыми условиями без итерации

Учитывая фрейм данных condition, определенный как:

0    [3, 4]
1       [2]

Я хочу, чтобы 0-я строка другого фрейма данных, столбцы 3 и 4, а также 1-я строка, столбец 2 были установлены на 0.

Например, учитывая другой фрейм данных df2:

        1         2       3         4  
0  0.275464  0.275404  0.2782  0.273485  
1  0.275464  0.275404  0.2782  0.273485 

После применения condition я хочу, чтобы df2 стал:

        1         2       3         4  
0  0.275464  0.275404  0.0000  0.0000  
1  0.275464  0.000000  0.2782  0.273485 

Есть ли хороший способ сделать это без перебора отдельных строк?

Когда вы говорите о фреймах данных, вы имеете в виду фреймы данных Pandas или просто полностью работаете с массивами numpy? В первом случае вам следует добавить к вопросу тег pandas.

Matt Pitkin 09.05.2024 11:26

@MattPitkin да, кадры данных панд. отредактировано

John Tan 09.05.2024 11:29

Какого типа ваше состояние? Это пустой массив?

Vardan Grigoryants 09.05.2024 12:14
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
57
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Возможное решение, которое:

  • Создает двумерный массив numpy с нужными индексами (он вычитает 1, чтобы привести имена столбцов в соответствие с индексами столбцов).
  • Создает логическую маску для выбора нужных элементов df.
  • Присваивает 0 нужным элементам df.

Кадр данных cond был создан следующим образом:

cond = pd.DataFrame({
    '0':    [[3, 4]],
    '1':       [[2]]

})

cond = cond.T

Решение:

indices = cond.explode(0).reset_index().astype(int).values - 1
mask = np.full(df.shape, False)
mask[indices[:, 0] + 1, indices[:, 1]] = True
df.values[mask] = 0

Выход:

          1         2       3         4
0  0.275464  0.275404  0.0000  0.000000
1  0.275464  0.000000  0.2782  0.273485

Вы создаете indices, но в ответе он, похоже, не используется.

Matt Pitkin 09.05.2024 11:44

Спасибо, @MattPitkin! Моя вина при вставке моего решения. Исправлено сейчас.

PaulS 09.05.2024 11:49

Используйте MultiLabelBinarizer для маски и установите 0 для 1 значений:

np.random.seed(2023)

df = pd.DataFrame(np.random.random(size=(2,6)))
print (df)
          0         1         2         3         4         5
0  0.321988  0.890422  0.588052  0.126596  0.141341  0.467896
1  0.022090  0.727275  0.524387  0.544935  0.456373  0.501382

condition = pd.Series([[3,4],[2]])

from sklearn.preprocessing import MultiLabelBinarizer

mlb = MultiLabelBinarizer()
mask = pd.DataFrame(mlb.fit_transform(condition),columns=mlb.classes_).eq(1)
print (mask)
       2      3      4
0  False   True   True
1   True  False  False

df[mask] = 0
print (df)
          0         1         2         3         4         5
0  0.321988  0.890422  0.588052  0.000000  0.000000  0.467896
1  0.022090  0.727275  0.000000  0.544935  0.456373  0.501382

Вы также можете сделать это следующим образом:

condition = [[3,4],[2]]

rows = []
cols = []
for i, items in enumerate(condition):
    rows.extend([i]*len(items))
    cols.extend(items)
    
df2.values[rows, cols] = 0

Вы также можете сделать это следующим образом:

condition = [[3,4],[2]]
condition_flatten = pd.Series(condition).explode().astype(int)
rows = condition_flatten.index
cols = condition_flatten.values
df2.values[rows, cols] = 0

Другие вопросы по теме