Проблема при выравнивании условного столбца в мультииндексе по тому же индексу - PullRequest
2 голосов
/ 26 марта 2019

Я пытаюсь добавить условный столбец, который просматривает col1 и возвращает True, если он равен «Hello», иначе False. Проблема в том, что он, кажется, размещает его в алфавитном порядке col1

df = pd.DataFrame({'col1': ['A','B','Hello','C'],'col2':['foo','bar','baz','foz'], 'col3 ':['3','1','3','4']})
df.set_index(['col1', 'col2'],inplace=True) 

df['col4'] = df.index.levels[0].str.contains('Hello')

Возвращается

           col3    col4
col1  col2             
A     foo      3  False
B     bar      1  False
Hello baz      3  False
C     foz      4   True

Но я хочу, чтобы он вернулся

           col3    col4
col1  col2             
A     foo      3  False
B     bar      1  False
Hello baz      3  True
C     foz      4  False

Ответы [ 3 ]

2 голосов
/ 26 марта 2019

Используйте eval:

df['col4'] = df.eval('col1 == "Hello"')
df

           col3    col4
col1  col2             
A     foo      3  False
B     bar      1  False
Hello baz      3   True
C     foz      4  False

Для частичного поиска строки используйте str.contains с engine='python'.

df['col4'] = df.eval('col1.str.contains("Hello")', engine='python')
df

           col3    col4
col1  col2             
A     foo      3  False
B     bar      1  False
Hello baz      3   True
C     foz      4  False

Другой вариант - запрос MultiIndex.get_level_values:

df['col4'] = df.index.get_level_values('col1') == 'Hello'
df

           col3    col4
col1  col2             
A     foo      3  False
B     bar      1  False
Hello baz      3   True
C     foz      4  False

Если это проблема частичного поиска строки, используйте str.contains здесь:

df['col4'] = df.index.get_level_values('col1').str.contains('Hello')
df

           col3    col4
col1  col2             
A     foo      3  False
B     bar      1  False
Hello baz      3   True
C     foz      4  False

Наконец, если вы выполняете сравнение на равенство (а не частичное)совпадение строк), вы можете назначить, используя loc и pd.IndexSlice:

df['col4'] = False
df.loc[pd.IndexSlice['Hello', :], 'col4'] = True
df

           col3    col4
col1  col2             
A     foo      3  False
B     bar      1  False
Hello baz      3   True
C     foz      4  False
0 голосов
/ 26 марта 2019

вместо

df.index.levels[0].str.contains('Hello')

Используйте

df.index.get_level_values(0).str.contains('Hello')

и оставьте все остальное таким же.

0 голосов
/ 26 марта 2019

Это потому, что index.levels[0] уже отсортировано, поэтому используйте reset_index:

df['col4'] = df.reset_index()['col1'].str.contains('Hello').tolist()

А теперь:

print(df)

Является:

           col3    col4
col1  col2             
A     foo      3  False
B     bar      1  False
Hello baz      3   True
C     foz      4  False
...