我有一个宠物名字和主人的数据集:
Pets Owners
dog James
dog Katelyn
rat Shelly
cat Bob
我希望能够在"所有者"列中搜索以找到名称Katelyn,然后为给定所有者打印出矢量名称。 到目前为止,我有这个:
def pet_name():
owner = input("What is the Owner name?")
# check to see if owner exist in pets dataset
# if ownderID exist then print corresponding pet names
if owner in pets['Owners']:
print( pets[['Pets','Owners']][pets.Owners == owner])
# if ownerID doesnt' exist
elif not age:
print("Sorry, this Owner doesn't exist. Try again!")
# if no ownerID has been entered at all
else:
print("You didn't enter any Owner. Try again!")
当我输入要搜索的名称时,它会自动转到代码的其他部分。 我怎样才能解决这个问题? 我应该使用itterows()吗?
不要使用iterrows。 简单使用loc .. pets.loc[pets.Owners == Katelyn, Pets]
代码的哪一部分? loc ..可以选择列的某些部分吗?
首先,让我们看看问题是什么,然后我们可以找到一种解决问题的方法。
In [1]: import pandas as pd
In [2]: pets = pd.read_csv('pets.csv')
In [3]: pets
Out[3]:
Pets Owners
0 dog James
1 dog Katelyn
2 rat Shelly
3 cat Bob
In [4]: type(pets["Owners"])
Out[4]: pandas.core.series.Series
我们可以看到pets是pandas.Series对象。现在问题显然出在这行代码中:
if owner in pets['Owners']:
这就是为什么不能将in运算符与pandas.Series一起使用的原因,但是基本上,这是因为Pandas的开发人员没有以可能使用这种"成员资格测试操作"的方式来实现此模块。因此,正如您自己提到的那样,它将始终返回False:
In [5]: owner in pets["Owners"]
Out[5]: False
现在,如果您想使用pets["Owners"],则可以这样做(如@piRSquared所建议):
In [6]: owner in pets["Owners"].values
Out[6]: True
但是,如果我们查看pandas.Series.values的文档:
Warning: We recommend using Series.array or Series.to_numpy(),
depending on whether you need a reference to the underlying data or a
NumPy array.
因此,我们可以这样做:
In [7]: owner in pets["Owners"].array
Out[7]: True
还有一种更好的方法,您是否想找出"给定主人的宠物",对吗?如果是这样,您可以这样做:
In [8]: pet = pets.loc[pets["Owners"] == owner,"Pets"]
In [8]: if pet.any():
...: print(pet)
...: else:
...: print("You didn't enter any Owner. Try again!")
Out[8]:
1 dog
Name: Pets, dtype: object
如您所见,这将打印一个pandas.Series对象。您已经提到您需要"矢量/列表/数组"格式的文件。尚不清楚,但是我认为情况是owner可以有多个pets,并且您要检查owner是否有任何pets,然后在列表中打印所有它们的pets类型的格式。如果是这样,可以使用pet.array。例如,如果我们修改您的数据集以使Katelyn拥有不止一只宠物:
Pets Owners
dog James
dog Katelyn
rat Katelyn
rat Shelly
cat Bob
然后我们可以看到它给出了一个列表:
In [9]: if pet.any():
...: print(pet.array)
...: else:
...: print("You didn't enter any Owner. Try again!")
Out[9]:
['dog', 'rat']
Length: 2, dtype: object
当检查owner in pets['Owners']是否在字典上下文中使用pets时,它会检查owner是否在pets的索引中。而是检查owner in pets['Owners'].values
也就是说,我宁愿看到pet_name这样写:
def pet_name():
owner = input("What is the Owner name?")
# check to see if owner exist in pets dataset
# if ownderID exist then print corresponding pet names
mask = pets['Owners'] == owner
if mask.any():
print(pets.loc[mask, ['Pets', 'Owners']])
# if ownerID doesnt' exist
elif not age:
print("Sorry, this Owner doesn't exist. Try again!")
# if no ownerID has been entered at all
else:
print("You didn't enter any Owner. Try again!")
这很好用!但是,我将需要使用矢量格式(列表/数组)。那么,我怎么能这样说呢?使用list()?
我不知道您的意思是"我需要它"。它是什么"?
mask和any()执行什么操作?
您应该尝试一下,看看。 mask是我设置为等于pets[Owners] == owner的变量名。它是布尔dtype的pandas.Series。如果任何值是True,则布尔系列的any方法将返回True。我这样做是因为我只需要一次评估等于owner的系列的所有成员,然后在对if语句的求值和对loc的调用中都使用它,以便进行切片数据框。
如何将结果放入矢量格式?作为列表?我应该使用list()吗?
结果是什么"?你还没有说清楚。 pets.loc[mask, [Pets, Owners]]?而且,"矢量格式"是什么意思?我也许可以猜出您的意思,但是如果您告诉我您要返回的内容会更容易。目前,您的函数未返回任何内容。它只打印东西。
因此,结果将显示相应的宠物类型以及所有者。宠物主人狗Katelyn我想要一些如何将其放入矢量格式的方法。向量格式,例如数组。我不希望它返回任何东西,我只希望它打印。
所以用return ...代替print(...)
建议使用pandas.Series.array代替pandas.Series.values。另外,您能否查看我的答案以查看是否有任何不一致之处?谢谢。
@ AmirA.Shabani和其他人。从Pandas 0.24版开始,属性array可用于Pandas Series对象,并将返回Pandas数组。现在它将适用于此之前的版本。因此,对于> = 0.24 owner in pets[Owner].array的版本将起作用。至于为什么推荐,病态必须更详细地探讨。