根据数据框中的子字符串提取部分字符串 - python

Extracting parts of a string based on substrings in a dataframe - python

我正在尝试提取一些 NBA 数据,但我的数据框有一个列,其中所有统计数据都在一个字符串中,由 Stats 列中的空格分隔,如图所示:例如。 29pt 15rb 3as 1bl ...等等。我想提取每个统计数据的值,以便我有一个用于得分、篮板、助攻、盖帽等的列。我 运行 遇到的问题是有些行可能不包含所有统计数据。例如,如果一名球员没有获得任何助攻,他们在统计数据列中的值可能如下所示:14pt 3rb 2bl。我无法提取每个统计数据所需的值,尤其是当该玩家不存在该统计数据时。我试图拆分字符串,以便将其值放入列表中,这很有希望,但我仍然无法弄清楚如何获取每个统计数据的值(如果该玩家甚至存在该统计数据)。任何建议、想法或指导将不胜感激。谢谢

SM

也许是这样的?

def parse_stat(stat):
    """takes 29pt and returns (int stat_value, str stat) as (29, "pt")"""
    i = 0
    while i < len(stat) and stat[i].isdigit():
        i += 1
    return int(stat[:i]), stat[i:]

def parse(string):
    substrings = string.split(' ')
    stats = {}
    for sub in substrings:
        val, stat = parse_stat(sub)
        stats[stat] = val
    return stats


if __name__ == "__main__":
    string = "9pt 15rb 3as 1bl"
    result = parse(string)
    print(result)
    print(result.get("pt", 0))
    print(result.get("fake", 0))
In: "9pt 15rb 3as 1bl"
Out: {'pt': 9, 'rb': 15, 'as': 3, 'bl': 1}
In: result.get("pt", 0)
Out: 9
In: result.get("fake", 0)
Out: 0

我们可以使用 Series.str.findall to extract the values (regex explained here) 逐步执行此操作,然后将其转换为 dict,我们将其返回到具有统计信息作为列标签和值的 DataFrame。

>>> import pandas as pd
>>> s = pd.Series(["29pt 15rb 3as 1bl", "14pt 3rb 2bl"])
>>> s
# 0    29pt 15rb 3as 1bl
# 1         14pt 3rb 2bl
>>> df = pd.DataFrame(
    s.str.findall(r"(\d+)(\w+)")
    .apply(lambda y: {k: v for v, k in y})
    .to_list()
)
>>> df = df.apply(pd.to_numeric)
>>> df
#    pt  rb   as  bl
# 0  29  15  3.0   1
# 1  14   3  NaN   2

然后可以将此 DataFrame 合并到您在索引上匹配的原始 DataFrame。


s.str.findall(r"(\d+)(\w+)")

此行应用定义两个捕获组(括号 ())的正则表达式 r"(\d+)(\w+)"。第一个捕获组查找数字(\d+),第二个捕获组查找单词字符(\w+,相当于[a-zA-Z0-9_]) .使用 findall returns 元组列表,例如

"29pt 15rb 3as 1bl" => [('29', 'pt'), ('15', 'rb'), ('3', 'as'), ('1', 'bl')]

接下来,.apply(lambda y: {k: v for v, k in y}) 被链接起来,在每一行上应用 lambda 函数。此函数将元组列表转换为字典,其中键是上面元组的第二个元素(pt、rb、...),值是数字。

[('29', 'pt'), ('15', 'rb'), ('3', 'as'), ('1', 'bl')]
# becomes
{'pt': '29', 'rb': '15', 'as': '3', 'bl': '1'}

最后,.to_list() 将我们的 pd.Series 转换为字典列表,我们可以使用它来创建一个可与原始数据合并的 DataFrame。


† 由于 \w+ 是匹配任何字母、数字或下划线的贪婪标记,因此最好使用 [a-zA-Z]+ 代替,它只会匹配字母。