【问题标题】:Pandas Dataframe str.match and str.contain熊猫数据框 str.match 和 str.contain
【发布时间】:2020-04-21 12:40:24
【问题描述】:

我有一个带有

的 json 文件
{
    "London": "Location A",   
    "Berlin": "Location B"  
}

我有另一个包含 2 列的数据框

Canberra is the capital of Australia            AUS  1
Berlin is the capital of Germany                GER  1
London is the capital of United Kingdom         UK   1
Berlin is also the art capital of Germany       GER  1
There is a direct flight from berlin to london  OTH  1
Interstate train service are halted             OTH  0

我正在尝试遍历json 的键并选择包含字符串(完全匹配)的所有行,就像当前键一样。

到目前为止我所尝试的:

temp_df = pd.read_csv(fileName , header=None)
df = (temp_df[temp_df[2] == 1]).reset_index(drop=True)
print(df)

with open(jsonFileName, encoding='utf-8') as jsonFile:
    jsonData = json.load(jsonFile)

for key in jsonData.keys():
    print(key)
    df2 = (df[df[0].str.lower().str.match(r"\b{}\b".format(key), case=False)]).reset_index(drop=True)
    print(df2.head())

当我尝试使用contains

 df2 = (df[df[0].str.lower().str.contains(r"\b{}\b".format(key), regex=True, case=False)]).reset_index(drop=True)
 print(df2.head())

预期输出:对于 key = London

London is the capital of United Kingdom         UK   1
There is a direct flight from berlin to london  OTH  1

但是,它的抛出:双倍的结果

London is the capital of United Kingdom         UK   1
London is the capital of United Kingdom         UK   1
There is a direct flight from berlin to london  OTH  1
There is a direct flight from berlin to london  OTH  1

任何关于此的指针都会有所帮助。

【问题讨论】:

  • 有什么问题?
  • 您没有返回语句,因此没有返回任何内容是有道理的。您期望的输出是什么?
  • @cggarvey,我已经更新了帖子。
  • 我很困惑。在您的原始帖子中,您说“我想使用新键和答案中的行列表更新 json 文件”,但您的预期输出不是 json。
  • @cggarvey,是的。现在,我只是打印它来验证。当我使用 contains 而不是 match 时,它可以工作。但是,包含不能进行全词匹配。

标签: python json pandas dataframe


【解决方案1】:

我仍然不完全清楚您要做什么,但您似乎正在寻找一系列字符串的不区分大小写的匹配项。

这是使用 Series.str.contains 的一种方法。

with open(jsonFileName, encoding='utf-8') as jsonFile:
    jsonData = json.load(jsonFile)

# convert the series of strings into lower-case
haystack = df[0].str.lower()

for key in jsonData.keys():

    # convert the key to lower-case
    needle = key.lower()

    # create a boolean indexer of any records in the haystack containing the needle
    matches = haystack.str.contains(needle)

    # create a subset of the dataframe with only those rows
    df2 = df[matches]
    print(df2)

您还可以使用 Series.apply 进行更多自定义:

    matches = haystack.apply(lambda x: needle in x)

以下是提供的示例数据的完整代码:

# setup the sample data objects
jsonData = {
    "Berlin": "Location A",
    "London": "Location B"
}

temp_df = pd.DataFrame([
    {0: 'Canberra is the capital of Australia', 1: 'AUS', 2: 1},
    {0: 'Berlin is the capital of Germany', 1: 'GER', 2: 1},
    {0: 'London is the capital of United Kingdom', 1: 'UK', 2: 1},
    {0: 'Berlin is also the art capital of Germany', 1: 'GER', 2: 1},
    {0: 'There is a direct flight from berlin to london', 1: 'OTH', 2: 1},
    {0: 'Interstate train service are halted', 1: 'OTH', 2: 0}
])

df = (temp_df[temp_df[2] == 1]).reset_index(drop=True)


# convert the series of strings into lower-case
haystack = df[0].str.lower()

for key in jsonData.keys():

    # convert the key to lower-case
    needle = key.lower()

    # create a boolean indexer of any records in the haystack containing the needle
    matches = haystack.str.contains(needle)

    # create a subset of the dataframe with only those rows
    df2 = df[matches]
    print(df2)

输出:

                                             0    1  2
2         London is the capital of United Kingdom   UK  1
4  There is a direct flight from berlin to london  OTH  1

                                                0    1  2
1                Berlin is the capital of Germany  GER  1
3       Berlin is also the art capital of Germany  GER  1
4  There is a direct flight from berlin to london  OTH  1

【讨论】:

  • 为什么df2 会抛出双重结果(两次)。
  • 鉴于您在原始帖子中提供的信息,事实并非如此。我添加了一个完整的 sn-p,包括设置您的测试数据框和 json 的代码。
猜你喜欢
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
  • 1970-01-01
  • 2021-11-09
  • 2020-06-03
相关资源
最近更新 更多