首页 > 解决方案 > pd.Serie 每行的平均“分数”,基于通过另一个分数系列映射的内容

问题描述

我有一个(非常大)包含关键字的系列(例如,每行包含多个用“-”分隔的关键字

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

这样的操作可能吗?还是有另一种快速的方法来实现这一目标?

标签: pythonpandasdataframeseries

解决方案


在 pandas 中处理字符串数据很慢,所以使用 map bySeries和的列表理解mean

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.nanget使用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]

推荐阅读