You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Python DataFrame的for循环与if语句,按Total列条件提取数据

问题描述

我尝试用for循环和if语句对Pandas DataFrame设置条件提取数据行,CSV格式不规范,已经手动设置列名:['Nama', 'Jabatan', 'Alamat', 'Klasifikasi Saham', 'Jumlah Lembar Saham', 'Total']。已知df.iloc[0:23]是高管数据,df.iloc[24:42]是股东数据,但把逻辑放进for循环后无法正常返回结果。需求是创建函数:当Total列值为'-'时返回高管数据,Total列非空时返回股东数据,该怎么修改for循环和if语句?

原代码如下:

import pandas as pd

input_csv_file = "./CSV/Officers_and_Shareholders.csv"

df = pd.read_csv(input_csv_file, skiprows=10, on_bad_lines='skip')
df.fillna('', inplace=True)
# df.drop([0, 3], inplace=True)
df.columns = ['Nama', 'Jabatan', 'Alamat', 'Klasifikasi Saham', 'Jumlah Lembar Saham', 'Total']

# print(df.shape)
# print(df.columns)
# print(df.iloc[:53])

# shareholders = df.iloc[24:42]
# print(shareholders)

# officers = df.iloc[0:23]
# print(officers)

dataframe = df.query("Total.ne('-')")

def get_shareholder_by_row_index():
    for column in df.columns:
        if object(df.iloc[column][:53]) == dataframe:
            shareholders = df.iloc[24:42]
            print(shareholders)
        # elif object(df[:53][column]) != dataframe:
        #     officers = df.iloc[0:23]
        #     print(officers)

期望股东数据输出:

24       PT CTCORP INFRASTRUKTUR D INDONESIA,  ...  Rp. 3.200.000.000
25                              Nomor SK :- I  ...                   
26      JalanKaptenPierreTendeanKavling12-14A  ...                   
27              PT INTRERPORT PATIMBAN AGUNG,  ...  Rp. 2.900.000.000
28                                Nomor SK :-  ...                   
29                                             ...                   
30                                             ...                   
31                                             ...                   
32                                             ...                   
33                                             ...                   
34                  PT PATIMBAN MAJU BERSAMA,  ...  Rp. 2.900.000.000
35                             Nomor SK :AHU-  ...                   
36                0061318.AH.01.01.TAHUN 2021  ...                   
37              Tanggal SK :30 September 2021  ...                   
38                                             ...                   
39                                             ...                   
40                      PT TERMINAL PETIKEMAS  ...  Rp. 1.000.000.000
41                                  SURABAYA,  ...                   
42                                Nomor SK :-  ... 

期望高管数据输出:

Nama  ...              Total
1                       NIK: 3171060201830005  ...                   
2                       NPWP: 246383541071000  ...                   
3               TTL: Jakarta, 02 Januari 1983  ...                   
5                       NIK: 1271121011700003  ...                   
6                       NPWP: 070970173112000  ...                   
7                TTL: Bogor, 10 November 1970  ...                   
8                         ARLAN SEPTIA ANANDA  ...                   
9                                      RASAM,  ...                   
10                      NIK: 3174051209620003  ...                   
11                      NPWP: 080878200013000  ...                   
12                 TTL: Jakarta, 12 September  ...                   
13                                       1962  ...                   
15                      NIK: 3171011605660004  ...                   
16                      NPWP: 070141650093000  ...                   
17                  TTL: Jakarta, 16 Mei 1966  ...                   
18                                FUAD RIZAL,  ...                   
21  PURNOMO, UTAMA RASRINIK: 3578032408610001  ...                   
22                      NPWP: 097468813615000  ...                   
23               TTL: SLEMAN, 24 Agustus 1961  ... 
解决方案

原代码问题分析

  1. 循环遍历列名完全没必要,需求是基于Total列的行值筛选,和列无关
  2. df.iloc[column]用法错误,iloc接收行索引,列名应使用df[column]
  3. 直接用object(...) == dataframe比较DataFrame无效,DataFrame不能直接判断相等

优化后的高效实现(推荐)

不需要用for循环,直接利用Pandas布尔索引筛选,同时结合已知行范围做双重验证(避免CSV格式不规范导致单条件筛选出错):

import pandas as pd

input_csv_file = "./CSV/Officers_and_Shareholders.csv"

df = pd.read_csv(input_csv_file, skiprows=10, on_bad_lines='skip')
df.fillna('', inplace=True)
df.columns = ['Nama', 'Jabatan', 'Alamat', 'Klasifikasi Saham', 'Jumlah Lembar Saham', 'Total']

def get_data_by_total_condition():
    # 筛选高管:Total为'-' 且 在已知高管行范围内
    officers = df[(df['Total'] == '-') & (df.index.isin(range(0,23)))]
    # 筛选股东:Total非空且不是'-' 且 在已知股东行范围内
    shareholders = df[(df['Total'] != '-') & (df['Total'] != '') & (df.index.isin(range(24,43)))]
    
    return officers, shareholders

# 调用函数并打印结果
officers_data, shareholders_data = get_data_by_total_condition()
print("=== 高管数据 ===")
print(officers_data)
print("\n=== 股东数据 ===")
print(shareholders_data)

若坚持使用for循环实现(不推荐,效率低)

如果一定要用循环遍历行判断,代码如下:

def get_data_with_loop():
    officers = []
    shareholders = []
    
    for idx, row in df.iterrows():
        # 结合行范围和Total列值判断
        if 0 <= idx <23 and row['Total'] == '-':
            officers.append(row)
        elif 24 <= idx <=42 and row['Total'] != '-' and row['Total'] != '':
            shareholders.append(row)
    
    # 转换为DataFrame返回
    return pd.DataFrame(officers), pd.DataFrame(shareholders)

# 调用函数
officers_loop, shareholders_loop = get_data_with_loop()
print(officers_loop)
print(shareholders_loop)

说明

  • 优先使用Pandas原生布尔索引,比循环高效得多,数据量大时差异更明显
  • 同时结合行索引范围和Total列值,是因为CSV格式不规范,双重验证能避免误判
  • 原代码中的df.query("Total.ne('-')")可简化为df[df['Total'] != '-'],更直观

内容的提问来源于stack exchange,提问作者htrgotoh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 02:30:59