我有一个(非常大的)系列,其中包含关键字(例如,每行包含多个以'-'分隔的关键字
In[5]: word_series
Out[5]:
0 the-cat-is-pink
1 blue-sea
2 best-job-ever
dtype: object
我有另一个系列,其中包含每个单词的得分属性(单词是索引,得分是值),例如:
In[7]: all_scores
Out[7]:
the 0.34
cat 0.56
best 0.01
ever 0.77
is 0.12
pink 0.34
job 0.01
sea 0.87
blue 0.65
dtype: float64
我的word_series中的所有单词都出现在我的分数中。我正在尝试根据all_scores中每个单词的平均得分找到一种将得分分配给word_series的每一行的最快方法。如果某行为n / a,则得分应为得分的平均值。
我尝试过以这种方式使用Apply,但是太慢了。
scores = word_series.apply(
lambda x: all_scores[x.split('-')].mean()).fillna(
all_scores.mean())
然后我以为我可以使用str.replace将all_words拆分为列,并可能使用此新矩阵M和我的单词(如M.mul(all_scores))执行矩阵乘法类型运算,其中M中的每一行都基于all_scores的索引。那将是第一步,要弄清平均值,然后我可以将其除以每行上的非na数
In[9]: all_words.str.split('-', expand=True)
Out[9]:
0 1 2 3
0 the cat is pink
1 blue sea None None
2 best job ever None
这样的操作可行吗?还是有另一种快速的方法来实现这一目标?
答案 0 :(得分:2)
在大熊猫中,处理字符串数据的速度很慢,因此对Series
和mean
的map使用列表理解:
from statistics import mean
L = [mean(all_scores.get(y) for y in x.split('-')) for x in word_series]
a = pd.Series(L, index=word_series.index)
print (a)
0 0.340000
1 0.760000
2 0.263333
dtype: float64
或者:
def mean(a):
return sum(a) / len(a)
L = [mean([all_scores.get(y) for y in x.split('-')]) for x in word_series]
a = pd.Series(L, index=word_series.index)
如果可能,某些值不匹配,请将参数np.nan
添加到get
并使用numpy.nanmean
:
L = [np.nanmean([all_scores.get(y, np.nan) for y in x.split('-')]) for x in word_series]
a = pd.Series(L, index=word_series.index)
或者:
def mean(a):
return sum(a) / len(a)
L = [mean([all_scores.get(y, np.nan) for y in x.split('-') if y in all_scores.index])
for x in word_series]
答案 1 :(得分:0)
这是一种方法
打印(a)
words
0 the-cat-is-pink
1 blue-sea
2 best-job-ever
打印(b)
all_scores
the 0.34
cat 0.56
best 0.01
ever 0.77
is 0.12
pink 0.34
job 0.01
sea 0.87
blue 0.65
b = b.reset_index()
打印(b)
index all_scores
0 the 0.34
1 cat 0.56
2 best 0.01
3 ever 0.77
4 is 0.12
5 pink 0.34
6 job 0.01
7 sea 0.87
8 blue 0.65
a['score'] = a['words'].str.split('-').apply(lambda x: sum([b[b['index'] == w].reset_index()['all_scores'][0] for w in x])/len(x))
输出
words score
0 the-cat-is-pink 0.340000
1 blue-sea 0.760000
2 best-job-ever 0.263333