【问题标题】:Regular expression to filter desired rows from pandas dataframe从熊猫数据框中过滤所需行的正则表达式
【发布时间】:2016-01-15 05:02:57
【问题描述】:

我正在处理相当混乱的数据:具有以下形式的关税表:

import pandas as pd
import numpy as np

data1 = np.array([u'Free (A, B, KR, FR), 5% (JP)', u'Free (A, B, FR), 5% (JP, KR))'])
data2 = np.array(['10101010', '10101020'])
data = {'hscode': data2, 'tariff' : data1}

df = pd.DataFrame(data, columns=['hscode', 'tariff'])

第一行显示国家(A、B、KR、FR)的关税为零,日本的关税为 5%,第二行显示 A、B、FR 的关税为零,而日本和日本的关税为 5%韩国。

我想为每一行找到国家'KR'的关税税率,这样我就可以得到下表:

'hscode' '关税'

10101010 0%

10101020 5%

所以,我想在每个单元格中找到县代码“KR”的关税税率。

【问题讨论】:

  • 你能否更清楚地解释一下data2与data1的关系以及与KR和(A,B,KR,FR)的关系?
  • 您好 Anzel,data2 是“统一关税代码”,data1 显示每个国家/地区的实际关税税率。 (A、B、KR、FR、JP)都表示国家,我想找到特定国家 KR 的关税税率。谢谢。
  • 我刚刚发布了一个不使用正则表达式的答案。正则表达式是强制性的吗?因为您只需在标题中说明它们。
  • 谢谢,法比安。我正在努力研究re,因为我经常遇到这种乱七八糟的文本数据。

标签: python regex pandas filter


【解决方案1】:

您可以将 apply 与正则表达式一起使用:

## -- End pasted text --

In [133]: import re

In [134]: df
Out[134]: 
     hscode                         tariff
0  10101010   Free (A, B, KR, FR), 5% (JP)
1  10101020  Free (A, B, FR), 5% (JP, KR))

In [135]: df['tariff'].apply(lambda x: ''.join(re.findall(r'.*(Free|\d+%).*\bKR\b', x)))
Out[135]: 
0    Free
1      5%
Name: tariff, dtype: object

说明:在关税范围内,如果字符串包含“KR”,则捕获“Free”或“x%”。

您可以创建一个函数来动态地将“KR”设置为查找变量。

【讨论】:

  • 安泽尔,你是我的天使!这很好用,但我仍然需要研究正则表达式。我不明白这段代码是如何工作的。看起来它试图在 x 中找到 (Free|\d+%),但我不知道在这个表达式中两个星 (*) 和一个点 (.) 做了什么。我也不知道这段代码如何处理括号。但是非常感谢!我会更多地研究这个!
  • @JohnShin 没问题 :) .* (点星号)表示零个或多个任何字符(实际上是任何字符), \b[string]\b 表示整个内容必须包含完整的[字符串],以它作为开始 - 结束
  • @JohnShin 我使用的正则表达式基本上是一个模式匹配说好的——前面有或没有任何东西。*没有括号(我没有捕获它),它必须是“免费”或带括号的“x%”(我想捕获该值),它必须包含的字符串之间也可以有任何内容,即。 “KR”......所以最后你只捕获(......)
  • 感谢您的解释。看起来正则表达式比我想象的更强大。非常感谢!!
  • @JohnShin,确实如此,但在转向正则表达式之前,请始终尝试以您能想到的最简单的方式解决这个问题。有时简单的 if/then 就可以了,您可以消除不必要的开销
【解决方案2】:
    import pandas as pd
    import numpy as np

    data1 = np.array([u'Free (A, B, KR, FR), 5% (JP)', u'Free (A, B, FR), 5% (JP, KR))'])
    data2 = np.array(['10101010', '10101020'])

    df = []
    for i, element in enumerate(data1):
        free, five = element.lstrip('Free (').rstrip(')').split('), 5% (')
        for country in free.split(', '):
            row = [data2[i], 'Free', country]
            df.append(row)
        for country in five.split(', '):
            row = [data2[i], '5%', country]
            df.append(row)
    df = pd.DataFrame(df, columns = ['hscode', 'tariff', 'country'])
    print df.query('country == "KR"')

给了

     hscode tariff country
2  10101010   Free      KR
9  10101020     5%      KR

【讨论】:

  • 感谢您的回答。但是,如果有多个关税税率,即,如果可以是 4%、5%、1% 等等……我有超过 20,000 行。谢谢。
猜你喜欢
  • 2018-01-11
  • 2021-08-09
  • 1970-01-01
  • 2021-03-13
  • 2019-07-18
  • 2017-06-18
  • 2013-02-25
  • 2020-04-14
  • 2020-10-23
相关资源
最近更新 更多