setting a multi index does not allow access using .loc?

Question:

import pandas as pd
df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
empty_row_index = ("zero_scan")
empty_row_df = pd.DataFrame({c: [None] for c in df.columns})
empty_row_df.index = [empty_row_index]
df2 = pd.concat([empty_row_df, df])result = df2.loc[df2.index[0], :]

works

import pandas as pd
df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
empty_row_index = ("zero_scan",)
empty_row_df = pd.DataFrame({c: [None] for c in df.columns})
empty_row_df.index = [empty_row_index]
df2 = pd.concat([empty_row_df, df])result = df2.loc[df2.index[0], :]

key error.

Notice "zero_scan" vs "zero_scan",.

This is a test program, and I need the "zero_scan", version using multi index.

How to correct the access to the row by index?

Asked By: Gulzar

||

Answers:

import pandas as pd

df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
empty_row_index = ("zero_scan",)
empty_row_df = pd.DataFrame({c: [None] for c in df.columns})
empty_row_df.index = [empty_row_index]
df2 = pd.concat([empty_row_df, df])
result = df2.loc[[df2.index[0]], :]
print(result)

enter image description here

Answered By: Mohammed Jhosawa

This might be counterintuitive but pandas unpacks a single tuple when this one is passed to loc in order to match the corresponding MultiIndex levels (1st element <> 1st-level, 2nd-element<> 2nd-level). And since your df2 has a flat index, the KeyError is trigerred.

As a solution, you need to enclose your tuple with square brackets [] or use a slice indexer :

# df2.index.nlevels shows `1`

# df2.index[0] is equal to ("zero_scan", )

result = df2.loc[[df2.index[0]], :] # or slice(df2.index[0])

Output :

print(result)
    
                 a     b
(zero_scan,)  None  None
Answered By: Timeless