假设我有一个像这样的数据帧
import pandas as pd
df = pd.DataFrame([[1, 2, 1], [1, 3, 2], [4, 6, 3], [4, 3, 4], [5, 4, 5]], columns=['A', 'B', 'C'])
>> df
A B C
0 1 2 1
1 1 3 2
2 4 6 3
3 4 3 4
4 5 4 5
Run Code Online (Sandbox Code Playgroud)
原始表格更复杂,列数和行数更多.
我想获得符合某些标准的第一行.例子:
但是,如果没有任何行满足特定条件,那么我想在我按A(或其他情况由B,C等)对其进行排序后得到第一行
我能够通过迭代数据帧来做到这一点(我知道掷骰子:P).所以,我更喜欢用更加pythonic的方式来解决它.
Tgs*_*591 44
对于pandas切片,本教程非常好.一定要检查一下.在某些片段上...要使用条件切片数据框,请使用以下格式:
>>> df[condition]
Run Code Online (Sandbox Code Playgroud)
这将返回您可以使用索引编制的数据帧的一部分iloc
.以下是您的示例:
获取A> 3的第一行(返回第2行)
>>> df[df.A > 3].iloc[0]
A 4
B 6
C 3
Name: 2, dtype: int64
Run Code Online (Sandbox Code Playgroud)如果你真正想要的是行号,而不是使用iloc
,那就是df[df.A > 3].index[0]
.
获取A> 4 AND B> 3的第一行:
>>> df[(df.A > 4) & (df.B > 3)].iloc[0]
A 5
B 4
C 5
Name: 4, dtype: int64
Run Code Online (Sandbox Code Playgroud)获取A> 3 AND(B> 3 OR C> 2)的第一行(返回第2行)
>>> df[(df.A > 3) & ((df.B > 3) | (df.C > 2))].iloc[0]
A 4
B 6
C 3
Name: 2, dtype: int64
Run Code Online (Sandbox Code Playgroud)现在,在您的上一个案例中,我们可以编写一个函数来处理返回降序排序帧的默认情况:
>>> def series_or_default(X, condition, default_col, ascending=False):
... sliced = X[condition]
... if sliced.shape[0] == 0:
... return X.sort_values(default_col, ascending=ascending).iloc[0]
... return sliced.iloc[0]
>>>
>>> series_or_default(df, df.A > 6, 'A')
A 5
B 4
C 5
Name: 4, dtype: int64
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,它返回第4行.
Bou*_*oud 11
对于现有比赛,请使用query
:
df.query(' A > 3' ).head(1)
Out[33]:
A B C
2 4 6 3
df.query(' A > 4 and B > 3' ).head(1)
Out[34]:
A B C
4 5 4 5
df.query(' A > 3 and (B > 3 or C > 2)' ).head(1)
Out[35]:
A B C
2 4 6 3
Run Code Online (Sandbox Code Playgroud)
您可以使用切片和头部处理前 3 个项目:
df[df.A>=4].head(1)
df[(df.A>=4)&(df.B>=3)].head(1)
df[(df.A>=4)&((df.B>=3) * (df.C>=2))].head(1)
万一没有返回的情况,你可以用 try 或 if 来处理......
try:
output = df[df.A>=6].head(1)
assert len(output) == 1
except:
output = df.sort_values('A',ascending=False).head(1)
Run Code Online (Sandbox Code Playgroud)
对于“一旦找到满足要求的第一行/记录就返回值并且不迭代其他行”这一点,以下代码将起作用:
def pd_iter_func(df):
for row in df.itertuples():
# Define your criteria here
if row.A > 4 and row.B > 3:
return row
Run Code Online (Sandbox Code Playgroud)
它比Boolean Indexing
处理大型数据框更有效。
为了使上面的函数更适用,可以实现 lambda 函数:
def pd_iter_func(df: DataFrame, criteria: Callable[[NamedTuple], bool]) -> Optional[NamedTuple]:
for row in df.itertuples():
if criteria(row):
return row
pd_iter_func(df, lambda row: row.A > 4 and row.B > 3)
Run Code Online (Sandbox Code Playgroud)
正如“镜子”问题的答案中提到的,pandas.Series.idxmax
这也是一个不错的选择。
def pd_idxmax_func(df, mask):
return df.loc[mask.idxmax()]
pd_idxmax_func(df, (df.A > 4) & (df.B > 3))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
87822 次 |
最近记录: |