Комбинация Dataframe.lookup и карты, приводящая к ошибке метки столбца - PullRequest
2 голосов
/ 22 апреля 2019

У меня есть большой массив данных, состоящий из (1200, 10) в основном строки, где я должен добавить новый столбец, скажем «Z», на основе существующего справочного столбца, скажем «Y», значения которого «A», «B» , 'C' или неизвестно (NaN или другое), из этого мне нужно выбрать один из трех соответствующих столбцов в df, скажем 'D', 'E', 'F', или вывести NaN и добавить это значение в качестве столбца ' Z». В настоящее время у меня есть следующий код:

df = pd.DataFrame({'T': {0: '.', 1: '.', 2: '.', 3: '.'}, 
                   'G': {0: '.', 1: '.', 2: '.', 3: '.'}, 
                   'D': {0: 4, 1: 1, 2: 5, 3: 3}, 
                   'E': {0: 6, 1: 2, 2: 7, 3: 2}, 
                   'F': {0: 8, 1: 3, 2: 9, 3: 1}, 
                   'K': {0: '.', 1: '.', 2: '.', 3:'.'}, 
                   'Y': {0: 'A', 1: 'B', 2: 'B', 3: np.nan}})

d = {'A': 'D', 'B': 'E', 'C': 'F'}
df['Z'] = df.lookup(df.index, df.Y.map(d))

Проблема в том, что поиск ломается, где Y - неизвестное значение. и в конкретном коде Y.unique () выдает что-то вроде (A, B, C, NaN, nan). Так что мне было интересно, есть ли способ использовать метод поиска, который выводит Z в NaN, где Y - это NaN или неизвестно за пределами данного слова?


    T   G   D   E   F   K   Y   Z
0   .   .   4   6   8   .   A   4.0
1   .   .   1   2   3   .   B   2.0
2   .   .   5   7   9   .   B   7.0
3   .   .   3   2   1   .   NaN NaN

Ответы [ 3 ]

6 голосов
/ 22 апреля 2019

Вы можете использовать stack и reindex с zip для мультииндексов:

df['Z'] = df.stack().reindex(zip(df.index, df.Y.map(d))).reset_index(level=1, drop=True)

Вывод:

   T  G  D  E  F  K    Y    Z
0  .  .  4  6  8  .    A    4
1  .  .  1  2  3  .    B    2
2  .  .  5  7  9  .    B    7
3  .  .  3  2  1  .  NaN  NaN

Подробности:

Во-первых, давайте использоватьstack, переместите заголовок столбца в индекс строки информационного кадра, создав мультииндекс для информационного кадра.Где уровень 0 - исходный индекс строки, а уровень 1. - заголовки столбцов.

Теперь мы можем использовать reindex, чтобы отфильтровать только те индексы, которые нам нужны.Мультииндекс определяется с помощью кортежей.(level0, level1) следовательно, мы zip df.index и df.y.map (d) вместе создаем кортежи, используемые reindex.

Наконец, мы отбрасываем уровень = 1 мультииндекса, создаваяСтруктура исходного индекса и назначить новый столбец с этими значениями.

3 голосов
/ 22 апреля 2019

Я использую .values

df['Z'] = df.values[df.index, df.columns.get_indexer_for(df.Y.map(d))]
df
Out[135]: 
   T  G  D  E  F  K    Y    Z
0  .  .  4  6  8  .    A    4
1  .  .  1  2  3  .    B    2
2  .  .  5  7  9  .    B    7
3  .  .  3  2  1  .  NaN  NaN
3 голосов
/ 22 апреля 2019

Вы можете заменить отсутствующие значения некоторым вспомогательным значением, которого нет в столбце Y, и добавить новый вспомогательный столбец с тем же именем на DataFrame.assign для соответствия этим значениям:

df['Z'] = df.assign(tmp = np.nan).lookup(df.index, df.Y.map(d).fillna('tmp'))
print (df)
   T  G  D  E  F  K    Y    Z
0  .  .  4  6  8  .    A  4.0
1  .  .  1  2  3  .    B  2.0
2  .  .  5  7  9  .    B  7.0
3  .  .  3  2  1  .  NaN  NaN

Другое решение:

df[np.nan] = np.nan
df['Z'] = df.lookup(df.index, df.Y.map(d))
df = df.drop(np.nan, axis=1)
print (df)
   T  G  D  E  F  K    Y    Z
0  .  .  4  6  8  .    A  4.0
1  .  .  1  2  3  .    B  2.0
2  .  .  5  7  9  .    B  7.0
3  .  .  3  2  1  .  NaN  NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...