Pandas根据行信息选择列名

Pandas selecting the column name based on row information

我正在使用 Pandas 和 Python 3.5.1.

请假设一个名为 df:

的 DataFrame
    name1  name2  name3  name4
0     1      2      3      4
1     5      6      7      8
2     4      9      6      2
3     5      1      7      3

请注意,每一行中的所有值都是唯一的,在逐行的基础上,没有一列与另一列具有相同的值。

假设我有一个数字,例如 df[name3][1] 中的 7。有没有办法根据行 (1) 和值 (7) 仅获取 header、name3 列?

我不想要列本身中的任何内容,例如 3, 7, 6, or 7。我只想要 header.

一般解决方案 - 如果不匹配 rowval:

则工作
val = 70
row = 10

val = df.reindex(index=[row]).eq(val).squeeze()
col = next(iter(val.index[val]), 'no match')
print (col)
no match

另一种通用解决方案:

def get_col(row, val):
    try:
        a = df.loc[row].eq(val)
        c = a.index[a][0]
    except KeyError:
        c = 'not matched row'
    except IndexError:
        c = 'not matched value'
    return c

print (get_col(1, 7))
name3
print (get_col(10, 7))
not matched row
print (get_col(1, 70))
not matched value
print (get_col(10, 70))
not matched row

如果 始终存在 valDataFrame 中的行值的解决方案,因为如果不存在并且所有 Falses 都是 return 来自 df.loc[row].eq(val)然后 idxmax return 首先 False - 第一列名称。

val = 7
row = 1
col = df.loc[row].eq(val).idxmax()
#if want seelct by pocition use iloc
#col = df.iloc[row].eq(val).idxmax()
print (col)
name3

说明:

第 select 行 DataFrame.loc:

print (df.loc[row])
name1    5
name2    6
name3    7
name4    8
Name: 1, dtype: int64

然后比较eq

print (df.loc[row].eq(val))
name1    False
name2    False
name3     True
name4    False
Name: 1, dtype: bool

最后通过idxmax获取第一个True的索引值:

print (df.loc[row].eq(val).idxmax())
name3

您可以使用map方法来获得您想要的。 例如:

maps = [[],[(0,'name1'),(3,'name2')],[(0,'name2'),(2,'name4')],... ]

当你选择1 from df[name1][0]时,你会发现maps[1] = [(0,'name1'),(3,'name2')]并且你可以得到col名称,其中row = 0name1

整个代码如下:

maps = [(),() ..... ]
for col in data.columns:
    for row in range(len(data)):
        value = data[col][row]
        maps[value] = (row,col)

另一种选择是遍历键、值并使用下一个。

lookup = 14
row = 1
next((k for k,v in df.iloc[row,:].items() if v == lookup), 'No match')