我有一个像这样的csv文件:
Id col1 col2 col3
a 7.04 0.3 1.2
b 0.3 1.7 .1
c 0.34 0.05 1.3
d 0.4 1.60 3.1
我想将其转换为0.5的数据帧阈值。如果值大于或等于0.5,则计算列,否则不计算。
Id classes
a col1,col3
b col2
c col3
d col2,col3
我找到的最接近的解决方案是one。但是它处理的是单行,而不是多行。对于多行,我所拥有的最好的是遍历所有行。我需要一个没有for循环的简洁表达式。
答案 0 :(得分:2)
首先使用set_index
,然后使用numpy.where
按条件提取列。最后按list comprehension
删除空字符串:
df = df.set_index('Id')
s = np.where(df > .5, ['{}, '.format(x) for x in df.columns], '')
df['new'] = pd.Series([''.join(x).strip(', ') for x in s], index=df.index)
print (df)
col1 col2 col3 new
Id
a 7.04 0.30 1.2 col1, col3
b 0.30 1.70 0.1 col2
c 0.34 0.05 1.3 col3
d 0.40 1.60 3.1 col2, col3
类似于新DataFrame
:
df1 = pd.DataFrame({'classes': [''.join(x).strip(', ') for x in s],
'Id': df.index})
print (df1)
Id classes
0 a col1, col3
1 b col2
2 c col3
3 d col2, col3
如有必要,请使用,
删除空白:
df1 = pd.DataFrame({'classes': [''.join(x).strip(', ').replace(', ',',') for x in s],
'Id': df.index})
print (df1)
Id classes
0 a col1,col3
1 b col2
2 c col3
3 d col2,col3
详情:
print (s)
[['col1, ' '' 'col3, ']
['' 'col2, ' '']
['' '' 'col3, ']
['' 'col2, ' 'col3, ']]
替代apply
(更慢):
df1 = (df.set_index('Id')
.apply(lambda x: ','.join(x.index[x > .5]), 1)
.reset_index(name='classes'))
print (df1)
Id classes
0 a col1,col3
1 b col2
2 c col3
3 d col2,col3
答案 1 :(得分:2)
巧妙乘法后的理解......这假设Id
是索引。
df.assign(classes=[
','.join(s for s in row if s)
for row in df.ge(.5).mul(df.columns).values
])
col1 col2 col3 classes
Id
a 7.04 0.30 1.2 col1,col3
b 0.30 1.70 0.1 col2
c 0.34 0.05 1.3 col3
d 0.40 1.60 3.1 col2,col3
设置趣味技巧
str
的自定义子类,重新定义字符串添加以包含','
class s(str):
def __add__(self, other):
if self and other:
return s(super().__add__(',' + other))
else:
return s(super().__add__(other))
趣味技巧
df.ge(.5).mul(df.columns).applymap(s).sum(1)
Id
a col1,col3
b col2
c col3
d col2,col3
dtype: object