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.
列
一般解决方案 - 如果不匹配 row
或 val
:
则工作
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
如果 始终存在 val 和 DataFrame
中的行值的解决方案,因为如果不存在并且所有 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 = 0
是name1
整个代码如下:
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')
我正在使用 Pandas 和 Python 3.5.1.
请假设一个名为 df
:
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.
一般解决方案 - 如果不匹配 row
或 val
:
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
如果 始终存在 val 和 DataFrame
中的行值的解决方案,因为如果不存在并且所有 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 = 0
是name1
整个代码如下:
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')