【问题标题】:How to pick first occurence of value and get column name如何选择第一次出现的值并获取列名
【发布时间】:2020-04-17 04:02:55
【问题描述】:

这是我的数据框

     color    string   col_new   string.1    string.2
0    red       abc      qwer       abc         poi
1   blue       xyz      zxcv       123         xyz
2  green       pqr      uyit       tzv         pqr
3   pink       lmn      nbtw       lmn         lmn

对于每种颜色(在我的情况下是唯一的),我想在string 列中取值,并在同一行中找到该值的第一次出现并返回我找到该值的列名

例如。

row 0 should return string.1 row 1 should return string.2 row 2 should return string.2 row 3 should return string.1

我找到了 this 示例,但它在单个系列或列上实现,我希望它在该行中的所有列中搜索值。

【问题讨论】:

  • 如果在任何地方都找不到该值,您是否想要NaN
  • 它会确定我们如何生成原始表的值

标签: pandas


【解决方案1】:

DataFrame.filter 选择所有列,按string 列比较并按Trues 的第一个DataFrame.idxmax 获取列名称:

print (df.filter(regex='string\.\d'))
  string.1 string.2
0      abc      poi
1      123      xyz
2      tzv      pqr
3      lmn      lmn

s = df.filter(regex='string\.\d').eq(df['string'], axis=0).idxmax(axis=1)

print (s)
0    string.1
1    string.2
2    string.2
3    string.1
dtype: object

如果要选择没有前 2 个的所有列,请使用 DataFrame.iloc:

s = df.iloc[:, 2:].eq(df['string'], axis=0).idxmax(axis=1)
print (s)
0    string.1
1    string.2
2    string.2
3    string.1
dtype: object

如果可能,某些行无法匹配,请使用 numpy.whereDataFrame.any 以避免首先返回 False 列:

print (df)
   color string col_new string.1 string.2
0    red    abc    qwer      abc      poi
1   blue    xyz    zxcv      123      xyz
2  green    pqr    uyit      tzv      pqr
3   pink    lmn    nbtw      lmn      lmn
3   pink    lmn    nbtw      ttt      rrr <- no lmn values in another columns


mask = df.filter(regex='string\.\d').eq(df['string'], axis=0)
out = np.where(mask.any(axis=1), mask.idxmax(axis=1), np.nan)
print (out)
['string.1' 'string.2' 'string.2' 'string.1' nan]

原方案返回错误输出:

print (df.filter(regex='string\.\d').eq(df['string'], axis=0).idxmax(axis=1))
0    string.1
1    string.2
2    string.2
3    string.1
3       color
dtype: object

编辑:

print (df)
   color string col_new string.1 string.2
0    red    abc    qwer  abctyrf      poi
1   blue    xyz    zxcv      123      xyz
2  green    pqr    uyit      tzv      pqr
3   pink    lmn    nbtw      lmn      lmn

#default index
df = df.reset_index(drop=True)
#column for test
st = df['string']
#for eac hrow is tested subtring by st
s = df.filter(regex='string\.\d').apply(lambda x: x.str.contains(st.loc[x.name]), axis=1)
print (s)
   string.1  string.2
0      True     False
1     False      True
2     False      True
3      True      True

【讨论】:

  • 正要发布同样的内容...grrr :p
  • 2 是否表示要考虑选择哪一列?
  • 原来的解决方案有效。是否可以为我可以查看的列名设置过滤器?在我的情况下,有超过 1100 列,在某些行中,我查找的值出现在 col_new 中,但我确信它总是会出现在 string.some_number 中。我可以将其设置为仅在具有df.columns.str.contains('string') 的列中查找吗
  • @MurtazaHaji - 答案已编辑。更好的是使用regex 参数来查找模式string.number
  • 太棒了,这对我有用。我建议保留按索引选择值列的原始答案作为一个选项。
猜你喜欢
  • 1970-01-01
  • 2014-09-06
  • 1970-01-01
  • 2020-06-22
  • 1970-01-01
  • 1970-01-01
  • 2019-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多