我在Kaggle中使用这个泰坦尼克数据集作为titanic_df
,我创建了一个新列titanic_df['person']
,如果乘客低于16,则输入值为child,如果他/她是乘客的性别高于16.但if
条件未被检查,['person']
列将乘客的性别作为其值。
这就是我的所作所为:
titanic_df= pd.read_csv('train.csv')
for age in titanic_df['Age']:
if age < 16 :
titanic_df['person']= 'child'
if age > 16 :
titanic_df['person'] = titanic_df['Sex']
print titanic_df[:12]
答案 0 :(得分:2)
这种情况发生的原因是,对于循环的每次迭代,您都将整个 'person'
列设置为相等;然后发生在最后一次迭代中,第二个子句就是发挥作用的那个。
您可能希望使用DataFrame.apply
之类的内容。例如,在您的情况下,您可以执行类似
In [1]: import pandas as pd
...:
...: df = pd.DataFrame()
...: df['Sex'] = ['Male', 'Female', 'Male']
...: df['Age'] = [15, 20, 50]
...: df
...:
Out[1]:
Sex Age
0 Male 15
1 Female 20
2 Male 50
In [2]: df['Person'] = df.apply(lambda x: 'Child' if x['Age'] < 16 else x['Sex'], axis=1)
In [3]: df
Out[3]:
Sex Age Person
0 Male 15 Child
1 Female 20 Female
2 Male 50 Male
一般情况下,您很少需要手动循环浏览Series
/ DataFrame
。
编辑:另请注意,对于大型DataFrame,上述代码大大优于@ piRSquared的解决方案:
In [41]: n = 10**5
In [42]: df = pd.DataFrame()
In [43]: df['Sex'] = np.random.choice(['Male', 'Female'], size=n)
In [44]: df['Age'] = np.random.randint(1, 100, size=n)
In [46]: df.head(10)
Out[46]:
Sex Age
0 Female 15
1 Female 91
2 Female 50
3 Female 11
4 Female 59
5 Female 40
6 Female 50
7 Male 28
8 Male 13
9 Female 27
In [47]: %timeit np.where(df.Age.values < 16, 'Child', df.Sex.values)
100 loops, best of 3: 3.06 ms per loop
In [48]: %timeit df.apply(lambda x: 'Child' if x['Age'] < 16 else x['Sex'], axis=1)
1 loop, best of 3: 5.73 s per loop
答案 1 :(得分:2)
我将回应@fuglede所说的关于在每次迭代中通过行分配整个列的内容。但是,下面是使用numpy.where
借用@ fuglede的样本数据
df['Person'] = np.where(df.Age.values < 16, 'Child', df.Sex.values)
print(df)
Sex Age Person
0 Male 15 Child
1 Female 20 Female
2 Male 50 Male