pd.Serie每行的平均“得分”,基于通过另一得分系列映射的内容。

时间:2019-02-22 07:43:58

标签: python pandas dataframe series

我有一个(非常大的)系列,其中包含关键字(例如,每行包含多个以'-'分隔的关键字

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

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

2 个答案:

答案 0 :(得分:2)

在大熊猫中,处理字符串数据的速度很慢,因此对Seriesmean的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