将稀疏向量的字符串表示形式转换为 Pandas 数据帧
Convert string representations of sparse vectors into Pandas dataframe
我有一个向量 vec
,其中每个元素都是一个稀疏向量的字符串表示形式。
我想要的输出是 Pandas DataFrame
具有以下特征:
index: vec
index
columns: sparse vector indices
values: sparse vector values
稀疏向量以 <feature_index>:<feature_value>
格式编码,记录由单个 space 分隔。
以下是几行示例数据:
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
and 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
.
- 这不一定是纯粹的 Pandas 解决方案。例如,我查看了一些 sklearn
处理稀疏性的方法,但其中 none 似乎非常适合解决此任务。
- 我不确定这是否重要,但在此操作之后,我将结果 DataFrame
(称之为 dense
)与另一个 DataFrame
(称之为 df
)合并,使用dense
和 df
索引作为合并键。所以在这个例子中,vec
索引是 [0,1,2,3]
,输出 dense
需要保留这些索引。
我认为您可以使用 list comprehensions
- 首先用于拆分,然后使用 DataFrame
构造函数将其转换为 dicts
:
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
使用 NaN
和字符串获取 DataFrame
,因此对于数字转换是必要的:
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'>
我有一个向量 vec
,其中每个元素都是一个稀疏向量的字符串表示形式。
我想要的输出是 Pandas DataFrame
具有以下特征:
index:
vec
index
columns: sparse vector indices
values: sparse vector values
稀疏向量以 <feature_index>:<feature_value>
格式编码,记录由单个 space 分隔。
以下是几行示例数据:
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
and 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
.
- 这不一定是纯粹的 Pandas 解决方案。例如,我查看了一些 sklearn
处理稀疏性的方法,但其中 none 似乎非常适合解决此任务。
- 我不确定这是否重要,但在此操作之后,我将结果 DataFrame
(称之为 dense
)与另一个 DataFrame
(称之为 df
)合并,使用dense
和 df
索引作为合并键。所以在这个例子中,vec
索引是 [0,1,2,3]
,输出 dense
需要保留这些索引。
我认为您可以使用 list comprehensions
- 首先用于拆分,然后使用 DataFrame
构造函数将其转换为 dicts
:
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
使用 NaN
和字符串获取 DataFrame
,因此对于数字转换是必要的:
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'>