DataFrame中的条件选择| 熊猫数据框
DataFrame中的条件选择
考虑以下示例,
import numpy as np import pandas as pd fromnumpy.randomimport randn np.random.seed(102) df = pd.DataFrame(randn(5,4),['P','Q','R','S','T'],['A','B','C','D']) print(df)
输出结果
A B C D P 1.668068 0.925862 1.057997 -0.920339 Q 1.299748 0.331183 -0.509845 -0.903099 R -0.130016 -2.238203 0.973165 -0.024185 S -0.484928 -1.109264 -0.558975 1.042387 T -1.712263 0.136120 -0.464444 0.050980
如果我们在DataFrame上使用<符号,例如>0,则将dataFrame中的值与0进行比较,并以True/False返回。
print(df > 0) ''' Output: A B C D P True True True False Q True True False False R False False True False S False False False True T False True False True '''
现在,将df>0分配给布尔值bool_df
bool_df = df > 0 print(bool_df) ''' Output: A B C D P True True True False Q True True False False R False False True False S False False False True T False True False True '''
将bool_df传递给df,在下面我们可以看到,值为True的具有其原始值;如果值为False,则具有一个NAN。使用这种方法,我们可以在dataFrame中使用条件选择。
print(df[bool_df]) ''' Output: A B C D P 1.668068 0.925862 1.057997 NaN Q 1.299748 0.331183 NaN NaN R NaN NaN 0.973165 NaN S NaN NaN NaN 1.042387 T NaN 0.136120 NaN 0.050980 '''
以上可以单行实现,
print(df[df>0]) ''' Output: A B C D P 1.668068 0.925862 1.057997 NaN Q 1.299748 0.331183 NaN NaN R NaN NaN 0.973165 NaN S NaN NaN NaN 1.042387 T NaN 0.136120 NaN 0.050980 '''
而不是传递整个dataFrame,仅传递行/列,而不是返回null,这将仅返回条件为True的数据帧子集的行/列。
看一看“A”列,这里针对“R”,“S”,“T”的值小于0,因此对于这些行,您得到False,
print(df['A']) ''' Output: P 1.668068 Q 1.299748 R -0.130016 S -0.484928 T -1.712263 Name: A, dtype: float64 '''
print(df['A']>0) ''' Output: P True Q True R False S False T False Name: A, dtype: bool '''
使用对应于行的这一系列布尔值来根据列值过滤掉行,这意味着如果使用括号表示法将该系列传递到dataFrame中,则仅返回具有True值的A行(没有null值)回)。
print(df[df['A']>0]) ''' Output: A B C D P 1.668068 0.925862 1.057997 -0.920339 Q 1.299748 0.331183 -0.509845 -0.903099 '''
考虑条件选择的更多示例,从df中获取所有行,其中D<0
print(df) ''' Output: A B C D P 1.668068 0.925862 1.057997 -0.920339 Q 1.299748 0.331183 -0.509845 -0.903099 R -0.130016 -2.238203 0.973165 -0.024185 S -0.484928 -1.109264 -0.558975 1.042387 T -1.712263 0.136120 -0.464444 0.050980 '''
逐步获取子集dataFrame
print(df[df['D']<0]) #subset dataFrame ''' Output: A B C D P 1.668068 0.925862 1.057997 -0.920339 Q 1.299748 0.331183 -0.509845 -0.903099 R -0.130016 -2.238203 0.973165 -0.024185 '''
result_df = df[df['D']<0] print(result_df) ''' Output A B C D P 1.668068 0.925862 1.057997 -0.920339 Q 1.299748 0.331183 -0.509845 -0.903099 R -0.130016 -2.238203 0.973165 -0.024185 '''
print(result_df['B']) ''' Output: P 0.925862 Q 0.331183 R -2.238203 Name: B, dtype: float64 '''
一步即可检索子集dataFrame
print(df[df['D']<0]['B']) ''' Output: P 0.925862 Q 0.331183 R -2.238203 Name: B, dtype: float64 '''
从dataFrame检索多列
print(df[df['D']<0][['B','C']]) ''' Output: B C P 0.925862 1.057997 Q 0.331183 -0.509845 R -2.238203 0.973165 '''
尽管使用单行似乎有些混乱,但这是一种首选方式,因为使用多个步骤,代码在定义每个变量时会占用更多内存。但是,除非感到舒适,否则最好将其分解为多个步骤。
使用多个条件进行选择
python中实现多个条件的常规方法是使用'and'运算符。但是,如果我们在pandas函数中使用“和”运算符,则会得到“ValueError:系列的真值不明确”。考虑下面的例子
print(df[(df['D']<0) and (df['A']>0)]) ''' Output: Traceback (most recent call last): File "main.py", line 31, in <module> print(df[(df['D']<0) and (df['A']>0)]) File "/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/pandas/core/generic.py", line 1555, in __nonzero__ self.__class__.__name__ ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). '''
发生上述错误的原因是,在python中,“和”运算符可以处理布尔值的单个实例,而不是多个实例。df['D']<0导致多个布尔值实例,如下所示,
print(df['D']<0) ''' Output: P True Q True R True S False T False Name: D, dtype: bool '''
在熊猫中,为了使用和进行逻辑运算,我们必须使用&
print(df[(df['D']<0) & (df['A']>0)]) ''' Output: A B C D P 1.668068 0.925862 1.057997 -0.920339 Q 1.299748 0.331183 -0.509845 -0.903099 '''
'或'运算,使用'|'
print(df[(df['D']<0) | (df['A']>0)]) ''' Output: A B C D P 1.668068 0.925862 1.057997 -0.920339 Q 1.299748 0.331183 -0.509845 -0.903099 R -0.130016 -2.238203 0.973165 -0.024185 '''
重置索引
为了重置索引,请使用reset_index()以下示例中说明的方法,
print(df.reset_index()) ''' Output: index A B C D 0 P 1.668068 0.925862 1.057997 -0.920339 1 Q 1.299748 0.331183 -0.509845 -0.903099 2 R -0.130016 -2.238203 0.973165 -0.024185 3 S -0.484928 -1.109264 -0.558975 1.042387 4 T -1.712263 0.136120 -0.464444 0.050980 '''
在上面的示例中,索引被重置为数值,而现有索引被重置为列“index”。
reset_index()除非我们传递参数(inplace=True),否则该方法不会就位,如以下示例中所述,
print(df) ''' Output: A B C D P 1.668068 0.925862 1.057997 -0.920339 Q 1.299748 0.331183 -0.509845 -0.903099 R -0.130016 -2.238203 0.973165 -0.024185 S -0.484928 -1.109264 -0.558975 1.042387 T -1.712263 0.136120 -0.464444 0.050980 '''
print(df.reset_index(inplace=True)) ''' Output: index A B C D 0 P 1.668068 0.925862 1.057997 -0.920339 1 Q 1.299748 0.331183 -0.509845 -0.903099 2 R -0.130016 -2.238203 0.973165 -0.024185 3 S -0.484928 -1.109264 -0.558975 1.042387 4 T -1.712263 0.136120 -0.464444 0.050980 '''
设定索引
如下所述创建一个新列,
new_index = 'KA KL AP TS MH'.split() #creates a list print(new_index) ''' Output: ['KA', 'KL', 'AP', 'TS', 'MH'] '''
df['states'] = new_index print(df) ''' Output: index A B C D states 0 P 1.668068 0.925862 1.057997 -0.920339 KA 1 Q 1.299748 0.331183 -0.509845 -0.903099 KL 2 R -0.130016 -2.238203 0.973165 -0.024185 AP 3 S -0.484928 -1.109264 -0.558975 1.042387 TS 4 T -1.712263 0.136120 -0.464444 0.050980 MH '''
设置索引,就地设置(无法还原)
print(df.set_index('states')) ''' Output: index A B C D states KA P 1.668068 0.925862 1.057997 -0.920339 KL Q 1.299748 0.331183 -0.509845 -0.903099 AP R -0.130016 -2.238203 0.973165 -0.024185 TS S -0.484928 -1.109264 -0.558975 1.042387 MH T -1.712263 0.136120 -0.464444 0.050980 '''