我有一个向量vec
,其中每个元素都是稀疏向量的字符串表示
我想要的输出是具有以下特征的Pandas DataFrame
:
索引:
vec
索引
列:稀疏矢量索引
值:稀疏矢量值
稀疏向量使用格式<feature_index>:<feature_value>
进行编码,记录由单个空格分隔。
以下是几行示例数据:
vec = ["70:1.0000 71:1.0000 83:1.0000",
"3:2.0000 8:2.0000 9:3.0000",
"3:3.0000 185:1.0000 186:1.0000",
"3:1.0000 8:1.0000 289:1.0000"]
这是我的预期输出:
185 186 289 3 70 71 8 83 9
index
0 NaN NaN NaN NaN 1.0000 1.0000 NaN 1.0000 NaN
1 NaN NaN NaN 2.0000 NaN NaN 2.0000 NaN 3.0000
2 1.0000 1.0000 NaN 3.0000 NaN NaN NaN NaN NaN
3 NaN NaN 1.0000 1.0000 NaN NaN 1.0000 NaN NaN
我有一个使用from_records
和pivot
的工作解决方案,但它似乎笨拙且效率低下:
import pandas as pd
dense = pd.DataFrame()
for i, row in enumerate(vec):
tups = []
for entry in row.split():
tups.append(tuple([x for x in entry.split(':')]))
dense = pd.concat([dense,
(pd.DataFrame
.from_records(tups,
index=[i]*len(tups),
columns=['key','val'])
.reset_index()
.pivot(index='index',
columns='key',
values='val')
)
])
任何人都可以建议更清洁的方法,理想情况下更好地使用Pandas功能吗?
我正在使用的实际数据集相当大,所以如果可能的话,我想利用原生Pandas中的性能优化。
注意:
- 输出索引不需要标记为index
- 这不一定是纯粹的熊猫解决方案。例如,我看了一些处理稀疏性的sklearn
方法,但是它们都不适合解决这个任务。
- 我不确定这是否重要,但在此操作之后,我将结果DataFrame
(称之为dense
)与另一个DataFrame
合并(称之为df
), dense
和df
索引作为合并键。因此,在此示例中,vec
索引为[0,1,2,3]
,输出dense
需要保留这些索引。
答案 0 :(得分:1)
我认为您可以使用list comprehensions
- 首先进行拆分,然后使用dicts
构造函数将其转换为DataFrame
:
print ([dict([y.split(':') for y in (x.split())]) for x in vec])
[{'83': '1.0000', '70': '1.0000', '71': '1.0000'},
{'8': '2.0000', '3': '2.0000', '9': '3.0000'},
{'185': '1.0000', '186': '1.0000', '3': '3.0000'},
{'289': '1.0000', '8': '1.0000', '3': '1.0000'}]
df = pd.DataFrame([dict([y.split(':') for y in (x.split())]) for x in vec])
print (df)
185 186 289 3 70 71 8 83 9
0 NaN NaN NaN NaN 1.0000 1.0000 NaN 1.0000 NaN
1 NaN NaN NaN 2.0000 NaN NaN 2.0000 NaN 3.0000
2 1.0000 1.0000 NaN 3.0000 NaN NaN NaN NaN NaN
3 NaN NaN 1.0000 1.0000 NaN NaN 1.0000 NaN NaN
使用DataFrame
和字符串获取NaN
,因此需要进行数值投射:
print (type(df.loc[0,'70']))
<class 'str'>
df = df.astype(float)
print (df)
185 186 289 3 70 71 8 83 9
0 NaN NaN NaN NaN 1.0 1.0 NaN 1.0 NaN
1 NaN NaN NaN 2.0 NaN NaN 2.0 NaN 3.0
2 1.0 1.0 NaN 3.0 NaN NaN NaN NaN NaN
3 NaN NaN 1.0 1.0 NaN NaN 1.0 NaN NaN
print (type(df.loc[0,'70']))
<class 'numpy.float64'>