Эффективная замена значений в каждой строке кадра данных pandas на основе условия

Я хотел бы работать с кадром данных pandas, чтобы получить странный, но желаемый выходной фрейм данных. Для каждой строки я бы хотел, чтобы любые значения 0,0 были заменены пустой строкой (''), а все значения 1,0 заменены значением индекса. Любое заданное значение в строке может быть только 1,0 или 0,0.

Вот некоторые примеры данных:

# starting df
df = pd.DataFrame.from_dict({'A':[1.0,0.0,0.0],'B':[1.0,1.0,0.0],'C':[0.0,1.0,1.0]})
df.index=['x','y','z']
print(df)

Как выглядит ввод df:

     A    B    C
x  1.0  1.0  0.0
y  0.0  1.0  1.0
z  0.0  0.0  1.0

Как бы я хотел, чтобы вывод df выглядел так:

   A  B  C
x  x  x   
y     y  y
z        z

Пока у меня есть этот довольно неэффективный, но, казалось бы, рабочий код:

for idx in df.index:
    df.loc[idx] = df.loc[idx].map(str).replace('1.0',str(idx))
    df.loc[idx] = df.loc[idx].map(str).replace('0.0','')

Может ли кто-нибудь предложить эффективный способ сделать это?

Реальный фрейм данных, с которым я буду работать, имеет форму (4548, 2044), а значения всегда будут плавающими (1,0 или 0,0), как в примере. Я манипулирую данными usher_barcodes.csv из «raw.githubusercontent.com/andersen-lab/Freyja/main/freyja/data/…» в формат, требуемый другим конвейером, где заголовки столбцов являются именами родословных, а значения мутации (взято из указателя). Заголовки столбцов и значения индексов, вероятно, будут разными каждый раз, когда мне нужно запустить этот код, потому что назначения происхождения постоянно меняются.

Спасибо!

Хорошо, но почему? Какую более широкую проблему вы решаете? Что представляет собой фрейм данных 4548x2044? Продажи? Генетика? И являются ли ваши значения dataframe логическими, плавающими или строковыми? Не сообщая нам контекст, это проблема XY

smci 14.02.2023 07:41

Значения фрейма данных всегда будут с плавающей запятой (1,0 или 0,0), как в примере. Я манипулирую данными usher_barcodes.csv из «raw.githubusercontent.com/andersen-lab/Freyja/main/freyja/d‌​ata/…» в формат, требуемый другим конвейером, где заголовки столбцов являются родословными имена и значения являются мутациями (взятыми из индекса).

frustrated_bioinformatician 14.02.2023 23:59

Frustrated_bioinformatician: хорошо, пожалуйста, отредактируйте этот контекст в вопросе. Я рекомендую вам не заменять одно значение на (строковое) значение индекса, покажите нам следующее вычисление, давайте выясним, как получить доступ к значениям индекса (например, посмотрите на df.to_records()). В конечном счете, я предполагаю, что он используется только в каком-то строковом формате; но есть и другие способы реализовать это, поэтому, вероятно, лучше хранить их как единицы/нули.

smci 15.02.2023 00:22

Спасибо за ваши предложения. Хорошо это или плохо, конвейер принимает в качестве входных данных файл CSV, где каждый столбец содержит диагностические мутации для каждой интересующей линии (заголовки столбцов). По своей природе не все столбцы имеют одинаковое количество значений, и формат 1.0/0.0 не будет принят. Вот как выглядит лист мутаций тестового ввода: raw.githubusercontent.com/BIMSBbioinfo/pigx_sars-cov-2/main/‌​…

frustrated_bioinformatician 15.02.2023 00:46
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
Учебник по веб-скрапингу
Учебник по веб-скрапингу
Привет, ребята... В этот раз мы поговорим о веб-скрейпинге. Целью этого обсуждения будет узнать и понять, что такое веб-скрейпинг, а также узнать, как...
Тонкая настройка GPT-3 с помощью Anaconda
Тонкая настройка GPT-3 с помощью Anaconda
Зарегистрируйте аккаунт Open ai, а затем получите ключ API ниже.
1
4
94
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете просто сделать:

for idx, row in df.iterrows():
    df.loc[idx] = ['' if val == 0 else idx for val in row]

Который дает:

   A  B  C
x  x  x   
y     y  y
z        z
Ответ принят как подходящий

Используйте numpy.where с преобразованием индекса вещания в массив numpy:

df = pd.DataFrame(np.where(df.eq(1), 
                           df.index.to_numpy()[:, None], 
                           ''),
                   index = df.index, 
                   columns = df.columns)

print(df)
   A  B  C
x  x  x   
y     y  y
z        z

Производительность с данными по размеру (4548,2044):

np.random.seed(2023)
df = pd.DataFrame(np.random.choice([0.0,1.0], size=(4548,2044))).add_prefix('c')
df.index = df.index.astype(str) + 'r'
# print (df)

In [87]: %timeit df.eq(1).mul(df.index, axis=0)
684 ms ± 36.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [90]: %timeit pd.DataFrame(np.where(df.eq(1),df.index.to_numpy()[:, None],''),index = df.index, columns = df.columns)
449 ms ± 26.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Воспользуйтесь тем, что 1*'x' -> 'x' и 0*'x' -> '':

out = df.eq(1).mul(df.index, axis=0)

NB. eq(1) преобразует число с плавающей запятой в логическое, поскольку True эквивалентно 1. Вы также можете использовать astype(int), если у вас есть только 0./1..

Выход:

   A  B  C
x  x  x   
y     y  y
z        z

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