使用另一个DataFrame中的文本选择Pandas DataFrame

2 投票
2 回答
1098 浏览
提问于 2025-04-18 10:43

简单说明一下:我之前用的是R语言,现在想转到pandas(在python 3.3.3上运行)。

我想通过数据框里的文本来选择某些行。这是个基本操作,但我对语法有点搞不清楚。

比如说,有这个数据框(抱歉换行了,但我想让例子更清楚):

films = pandas.DataFrame({'$title':[  "The Godfather",
                                      "Pulp Fiction",
                                      "The Godfather: Part II",
                                      "Fight Club"],

                      '$director': [  "Coppola, Francis Ford",
                                      "Tarantino, Quentin",
                                      "Coppola, Francis Ford",
                                      "Fincher, David"]})

如果我想选择所有由第一位导演“Coppola, Francis Ford”制作的电影,我用的命令是:

In [1]: director = films.iloc[[1]]["director"]

In [2]: director

        1    Coppola, Francis Ford
        Name: director, dtype: object

In [3]: a = films[ films["director"] == director ]

        ValueError: Series lengths must match to compare

如果我这样做:

In [4]: a = films[ films["director"] == str(director) ]

我得到的是一个空的数据框。到底发生了什么?感觉我漏掉了什么。

2 个回答

1

我觉得 films[ films["director"] == films.ix[0, 'director' ]] 这个写法就可以了。

之所以 films.iloc[[1]]["director"] 不好用,是因为它返回的是一个 Series,而不是一个 string(字符串)。

如果你想用 iloc,可以这样写:films.iloc[1]["director"],而不是 films.iloc[[1]]["director"]

另外:

In [241]:

str(films.iloc[[1]]["director"])
Out[241]:
'1    Tarantino, Quentin\nName: director, dtype: object'

所以,films[ films["director"] == str(director) ] 这个写法不会匹配到任何东西,结果会返回一个空的数据框。

3

好的,首先我看到你在从R转到Python的过程中犯了一些常见的风格和语法错误:

  • 你在列名上不需要使用$符号,这样反而会让选择列的方式更简单。比如,如果列名是'director',你可以直接写films.director(前提是这个名字是有效的Python标识符,这样才能用这种简化的写法)
  • 在Python中,索引是从0开始的,而不是从1开始,所以你要选择第一个导演时应该用films.director[0]

假设你已经把DataFrame定义中的$符号去掉了,你可以这样选择电影:

In [16]: films[films['director'] == films['director'][0]]
Out[16]:
                director                   title
0  Coppola, Francis Ford           The Godfather
2  Coppola, Francis Ford  The Godfather: Part II

或者可以更简洁地写成films[films.director == films.director[0]]

使用你原来的DataFrame,你可以用以下方式进行查询:

director = films.iloc[[1]]['$director'][1]
films[films['$director'] == director]

一个错误是你最开始用'$director'定义了表格,然后又用'director'作为列名进行查询。

最后的[1]是必要的,因为你用一个列表[1]来索引DataFrame,而不是用一个值1,所以你得到了一个Series,正如CT Zhu已经注意到的那样。列表索引更适合选择多个任意元素,比如films.iloc[[1, 3]]。在你的情况下,写成

director = films.iloc[1]['$director']

会更清晰。此外,请注意,这样还是会得到塔伦蒂诺而不是科波拉。

撰写回答