Перекрестные ссылки на столбцы в одном фрейме данных Pandas Python

#python #pandas

#python #pandas

Вопрос:

** Я отредактировал образец df, чтобы два столбца были кортежами, а не целыми числами, чтобы проиллюстрировать проблему, с которой я сталкиваюсь при решении, как только я меняю данные с целых чисел на кортежи **

Я пытаюсь создать новый столбец в Pandas, значение которого будет зависеть от значения определенного столбца, присутствующего в другой строке в отдельных столбцах, и там, где найдено совпадение, используйте значение третьего столбца. столбцы.

Для иллюстрации см. Приведенный Ниже пример.

Я использую лямбда-функцию в df.apply() для выполнения следующего: в первой строке она будет фильтровать строки, где значение столбца «два» равно значению столбца «ноль», а там, где это происходит, она принимает значение столбца «один» и копируетэто в новый столбец «три».

df = pd.DataFrame([[(0,9),(1,9),(2,9),(3,9),(4,9)],[‘ a’, ‘b’, ‘c’, ‘d’, ‘e’],[(2,9),(3,9),(4,9),(5,9),(6,9)]]). транспонировать()

 df.columns = ['zero','one','two']

df['three] = df.apply(lambda x : df[df['zero'] == x['two']].loc[:,'one'], axis=1)
  

Обратите внимание, что столбец «два» и столбец «ноль» уникальны, поэтому результат фильтрации будет иметь одну строку.

Теоретически результатом столбца ‘three’ должно быть: ‘c’, ‘d’, ‘e’, ‘nan’, ‘nan’.

Спасибо

Ответ №1:

Просто установите строку zero в качестве индекса для удобного поиска столбца one .

Обновление: решение теперь работает для индексов кортежей.

 import pandas as pd
import numpy as np

df = pd.DataFrame([[0,1,2,3,4],['a','b','c','d','e'],[2,3,4,5,6]]).transpose()
df.columns = ['zero','one','two']

# set index for quick lookup    
df_indexed = df.set_index("zero")

# the indexed dataset look like this
df_indexed
Out[21]: 
     one two
zero        
0      a   2
1      b   3
2      c   4
3      d   5
4      e   6

# apply the mapping logic, taking df_indexed from outside the function
def f(el):
    return df_indexed.at[el, "one"] if el in df_indexed.index else np.nan

df["three"] = df["two"].apply(f)

print(df)
Out[18]: 
  zero one two three
0    0   a   2     c
1    1   b   3     d
2    2   c   4     e
3    3   d   5   NaN
4    4   e   6   NaN

# On the updated dataset
df
Out[71]: 
     zero one     two three
0  (0, 9)   a  (2, 9)     c
1  (1, 9)   b  (3, 9)     d
2  (2, 9)   c  (4, 9)     e
3  (3, 9)   d  (5, 9)   NaN
4  (4, 9)   e  (6, 9)   NaN
  

Комментарии:

1. Билл, твой ответ здесь отлично работает. Единственное, мой фактический индекс — это кортеж, и по какой-то причине это отбрасывает это. Я думаю, что это связано с el <class 'tuple'> тем df_index.index , что элементы while, когда я проверяю через type(df_indexed.index[0]) , просто приводят к «кортежу». Ошибка ключа выглядит следующим образом: KeyError: "None of [Index([(1, 1), (2, 1), (3, 1)], dtype='object', name='tenors')] are in the [index]" что заставляет меня думать, что мне нужно получить доступ к значению el ?

2. Я не могу понять. Для меня проблема связана только с нулевым, первым и вторым столбцами, но не с индексом, независимо от того, что содержит индекс. Можете ли вы привести пример? К вашему сведению, вы можете .reset_index() .set_index() разрешить переназначение столбца индекса без потери данных.

3. Я отредактировал приведенный выше пример df как кортежи в colmn ноль и два, что, похоже, отбрасывает решение…

4. Я, наконец, понял. Следует использовать .at[] вместо .loc[] , потому что ожидается, что будет возвращено ровно одно значение, независимо от того, какой индекс. Это действительно плохо, что я опускаю это. Теперь решение должно работать для индексов кортежей.:)

5. Хорошо, это здорово. Работает отлично. Большое спасибо за вашу помощь.