【问题标题】:Assigning values of words in a dictionary to dataframe contents将字典中单词的值分配给数据框内容
【发布时间】:2021-11-14 20:24:12
【问题描述】:

以下是数据框、字典和代码的示例,但对于庞大的字典效率极低。数据框的一列包含句子。代码从句子中提取每个单词,检查它是否在字典中并为其赋值。计算值的平均值(每句或每行)并将其保存在额外的列中。

import pandas as pd
    test_df = pd.DataFrame({
    '_id': ['1a','2b','3c','4d'],
    'column': ['und der in zu',
                'Kompliziertereswort something',
                'Lehrerin in zu [Buch]',
                'Buch (Lehrerin) kompliziertereswort']})

{'und': 20,
     'der': 10,
     'in':  40,
     'zu':  10,
     'Kompliziertereswort': 2,
     'Buch': 5,
     'Lehrerin': 5}

pat = fr"\b({'|'.join(map(re.escape, d))})\b"
test_df['score'] = test_df['column'].str.extractall(pat)[0].map(d).mean(level=0)

print(test_df)

  _id                               column  score
0  1a                        und der in zu   20.0
1  2b        Kompliziertereswort something    2.0
2  3c                Lehrerin in zu [Buch]   15.0
3  4d  Buch (Lehrerin) kompliziertereswort    5.0

由于浏览字典比使用正则表达式更有效,我相信必须有一种方法使用将句子拆分为单词并检查它们是否在字典中并计算平均。我还将字典转换为数据框并使用了explode(),但同样没有效率。

【问题讨论】:

  • 您是否尝试过分析您的代码?如果是,处理中最耗时的部分是什么?

标签: python pandas dictionary


【解决方案1】:

你可以试试:

test_df['score'] = test_df['column'].str.split(r'\W').explode() \
                                    .map(d).groupby(level=0).mean()

输出:

>>> test_df

  _id                               column  score
0  1a                        und der in zu   20.0
1  2b        Kompliziertereswort something    2.0
2  3c                Lehrerin in zu [Buch]   15.0
3  4d  Buch (Lehrerin) kompliziertereswort    5.0

【讨论】:

    【解决方案2】:

    想法是将split 值转换为单词,转换为系列,删除标点符号,映射和最后聚合mean

    import string
    
    test_df['score'] = (test_df['column'].str.split(expand=True)
                                         .stack()
                                         .str.strip(string.punctuation)
                                         .map(d)
                                         .groupby(level=0)
                                         .mean())
    print(test_df)
      _id                               column  score
    0  1a                        und der in zu   20.0
    1  2b        Kompliziertereswort something    2.0
    2  3c                Lehrerin in zu [Buch]   15.0
    3  4d  Buch (Lehrerin) kompliziertereswort    5.0
    

    或者可以使用dict.get 来映射拆分值:

    f = lambda x: np.nanmean([d.get(y, np.nan) for y in x.split()])
    test_df['score'] = test_df['column'].str.replace('[^\w\s]','', regex=True).apply(f)
      _id                               column  score
    0  1a                        und der in zu   20.0
    1  2b        Kompliziertereswort something    2.0
    2  3c                Lehrerin in zu [Buch]   15.0
    3  4d  Buch (Lehrerin) kompliziertereswort    5.0
    

    替代方案:

    f = lambda x: np.nanmean([d.get(y, np.nan) for y in x])
    test_df['score'] = test_df['column'].str.split(r'\W').apply(f)
    

    【讨论】:

    • 谢谢!第一个有效,但对于更大的数据集,它会抛出 DataError: No numeric types to aggregate。字典的值会不会有错误?
    • @johnnydoe - 你可以试试.stack().astype(str) 吗?
    猜你喜欢
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    相关资源
    最近更新 更多