Tạo tên khung dữ liệu trong vòng lặp python

Và tôi phải tạo một chức năng chính gọi một chức năng khác, sử dụng “vòng lặp for”, truy xuất vận động viên có thời gian nhanh nhất cho từng độ tuổi [10,11,12,13,14,15,16] cho một giới tính cụ thể . g. 'F'] và khoảng cách [e. g. ‘100m’]

Ví dụ
Đầu vào
Fastest_athletes = find_fastest_athletes[df,"100m","F",[10,11,12,13,14,15,16]]
đầu ra
{
10. {'tên'. 'Valerie', 'họ'. 'Lee', 'thời gian'. '17. 23’},
11. {'tên'. 'Aida', 'họ'. 'Aumiller', 'thời gian'. '15. 3’},
12. {'tên'. 'Lilia', 'họ'. 'Armstrong', 'thời gian'. '11. 31’},
13. {'tên'. 'Lilia', 'họ'. 'Armstrong', 'thời gian'. 'số 8. 84’},
14. {'tên'. 'Martha', 'họ'. 'Rừng', 'thời gian'. '9. 01'},
15. {'tên'. 'Diane', 'họ'. 'Lauria', 'thời gian'. 'số 8. 99'},
16. {'tên'. 'Yvonne', 'họ'. 'Pumphrey', 'thời gian'. 'số 8. 84’}
}

Tôi đã làm đoạn mã sau

# Function with the for loop
def find_fastest_athletes[df,distance,gender,ages]:
  for age in range[10,16]:
    fastest_athletes = df[[df["gender"] == gender] & [df["age"] == age]]
    fastest_athletes_sorted = fastest_athletes.sort_values[distance,ascending=True]
    fastest_athletes_value = fastest_athletes_sorted.iloc[[0]][["forename","surname","100m"]]
    athletes_data = fastest_athletes_value.to_string[index=False, header=False].split['  ']
    athletes_data_dict = {
        'forename': athletes_data[0].strip[],
        'surname': athletes_data[1],
        'time': float[athletes_data[2]]
        }
  return athletes_data_dict
  
# Main function
def main[filename='athletes.csv']:
    df = pd.read_csv[filename, index_col=0]
    df['100m'] = df['100m'].astype[float]
    print[find_fastest_athletes[df,'100m','F',[10,11,12,13,14,15,16]]]
    return
   
if __name__ == "__main__":
  main[]   

Với cách mã hóa của mình, tôi CHỈ nhận được kết quả là vận động viên nhanh nhất ở độ tuổi cuối cùng [16 tuổi] chứ không phải TẤT CẢ vận động viên nhanh nhất ở mỗi độ tuổi [10,11,12,13,14,15,16], tại sao vậy?

Ngoài ra, làm cách nào để thêm tuổi vào đầu mỗi dòng?

Này @Giorgina99, vì vậy DataFrames của gấu trúc và các vòng lặp for đi cùng nhau như nước với dầu—có nghĩa là, không hề. Chắc chắn, chúng thường hoạt động, ít nhất là đối với các vấn đề nhỏ như thế này, nhưng chúng dẫn đến mã phức tạp hơn [và do đó dễ bị lỗi] hơn mức cần thiết và có hiệu suất kém hơn rất nhiều đối với các tập dữ liệu lớn hơn [giả sử . Thay vào đó, bạn muốn sử dụng các thao tác numpy/pandas gốc [vector hóa] càng nhiều càng tốt, điều này dẫn đến mã đơn giản hơn và nhanh hơn nhiều. Trên thực tế, tôi đã có thể giúp một đồng nghiệp tăng tốc tập lệnh xử lý dữ liệu của cô ấy lên khoảng một triệu lần, chủ yếu bằng cách thay thế các vòng lặp for bằng các hoạt động

        athletes_data_dict = {
            'forename': fastest_athletes_sorted.iloc[0].loc["forename"],
            'surname': fastest_athletes_sorted.iloc[0].loc["surname"],
            'time': fastest_athletes_sorted.iloc[0].loc[distance]
            }
0 gốc và bên cạnh đó, ít dòng mã hơn. Nó chắc chắn cần học hỏi nhiều hơn một chút ở giao diện người dùng, nhưng trả cổ tức rất lớn trong dài hạn

Dù sao đi nữa, hãy giải quyết vấn đề đó, hãy xem mã của bạn. Với vấn đề của bạn là chỉ từ điển của vận động viên cuối cùng được trả về, tại sao lại như vậy? . Sau đó, khi vòng lặp kết thúc,

        athletes_data_dict = {
            'forename': fastest_athletes_sorted.iloc[0].loc["forename"],
            'surname': fastest_athletes_sorted.iloc[0].loc["surname"],
            'time': fastest_athletes_sorted.iloc[0].loc[distance]
            }
2 được trả về. Vì một từ điển mới được gán lại cho cùng một biến mỗi lần, nên chỉ giá trị cuối cùng [trong trường hợp này là giá trị cho
        athletes_data_dict = {
            'forename': fastest_athletes_sorted.iloc[0].loc["forename"],
            'surname': fastest_athletes_sorted.iloc[0].loc["surname"],
            'time': fastest_athletes_sorted.iloc[0].loc[distance]
            }
4] được trả về

Nếu bạn muốn trả về một từ điển với độ tuổi là khóa và từ điển của dữ liệu vận động viên là giá trị, bạn sẽ cần tạo từ điển phía trên vòng lặp

        athletes_data_dict = {
            'forename': fastest_athletes_sorted.iloc[0].loc["forename"],
            'surname': fastest_athletes_sorted.iloc[0].loc["surname"],
            'time': fastest_athletes_sorted.iloc[0].loc[distance]
            }
5 for [e. g.
        athletes_data_dict = {
            'forename': fastest_athletes_sorted.iloc[0].loc["forename"],
            'surname': fastest_athletes_sorted.iloc[0].loc["surname"],
            'time': fastest_athletes_sorted.iloc[0].loc[distance]
            }
6 ngay bên dưới
        athletes_data_dict = {
            'forename': fastest_athletes_sorted.iloc[0].loc["forename"],
            'surname': fastest_athletes_sorted.iloc[0].loc["surname"],
            'time': fastest_athletes_sorted.iloc[0].loc[distance]
            }
7] và sau khi bạn tạo
        athletes_data_dict = {
            'forename': fastest_athletes_sorted.iloc[0].loc["forename"],
            'surname': fastest_athletes_sorted.iloc[0].loc["surname"],
            'time': fastest_athletes_sorted.iloc[0].loc[distance]
            }
8 bên trong vòng lặp, hãy thêm nó vào từ điển với khóa là tuổi của nó, e. g.
        athletes_data_dict = {
            'forename': fastest_athletes_sorted.iloc[0].loc["forename"],
            'surname': fastest_athletes_sorted.iloc[0].loc["surname"],
            'time': fastest_athletes_sorted.iloc[0].loc[distance]
            }
9, và
        fastest_athlete = fastest_athletes.loc[fastest_athletes[distance].idxmin[]]
        athletes_data_dict = {
            'forename': fastest_athlete.loc["forename"],
            'surname': fastest_athlete.loc["surname"],
            'time': fastest_athlete.loc[distance]
            }
0 thay vì cá nhân
        athletes_data_dict = {
            'forename': fastest_athletes_sorted.iloc[0].loc["forename"],
            'surname': fastest_athletes_sorted.iloc[0].loc["surname"],
            'time': fastest_athletes_sorted.iloc[0].loc[distance]
            }
2

Tuy nhiên, ít nhất là trên phiên bản Pandas của tôi [_______11_______2], bất kể sự thay đổi đó như thế nào, việc chạy mã của bạn không thành công với một ____11_______3 khi cố gắng lập chỉ mục _11_______4 vào ____1_______8, bởi vì _______11_______6 chỉ trả về một chuỗi duy nhất vì các giá trị trong ____11_______7 được phân tách bằng một . Việc thay đổi

        fastest_athlete = fastest_athletes.loc[fastest_athletes[distance].idxmin[]]
        athletes_data_dict = {
            'forename': fastest_athlete.loc["forename"],
            'surname': fastest_athlete.loc["surname"],
            'time': fastest_athlete.loc[distance]
            }
6 [hai dấu cách] thành
        fastest_athlete = fastest_athletes.loc[fastest_athletes[distance].idxmin[]]
        athletes_data_dict = {
            'forename': fastest_athlete.loc["forename"],
            'surname': fastest_athlete.loc["surname"],
            'time': fastest_athlete.loc[distance]
            }
6 [một dấu cách] khiến nó hoạt động với tôi, mặc dù tôi hoàn toàn không hiểu tại sao bạn lại làm bất kỳ điều gì trong số này. Hơn nữa, có một vấn đề khác—bạn đang mã hóa cứng
        athletes_data_dict = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
0 thành giá trị
        athletes_data_dict = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
1 khi bạn nhận được các cột được chỉ định trong
        athletes_data_dict = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
2, giá trị này sẽ trả về sai thời gian nếu
        athletes_data_dict = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
1 là bất kỳ thứ gì khác ngoài
        athletes_data_dict = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
4 [điều này xảy ra trong ví dụ của bạn]; . Và,
        athletes_data_dict = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
6 không trả về giá trị cuối cùng, vì vậy, thay vào đó,
        athletes_data_dict = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
7 của bạn phải là
        athletes_data_dict = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
8 nếu bạn muốn nó trả về các giá trị bao gồm cả [10, 16] [đồng thời, lưu ý rằng tuổi của bạn thực sự nằm trong khoảng từ 19]

Ngoài ra, chọn giá trị đầu tiên trong df được sắp xếp và các cột đã chỉ định, sau đó xuất giá trị này thành một chuỗi, sau đó tách chuỗi, sau đó lập chỉ mục các chuỗi theo cách thủ công để lấy các giá trị, sau đó biến thời gian trở lại thành một dấu phẩy, đóng gói tất cả trở lại

Bước đầu tiên để đơn giản hóa việc này, chúng ta có thể chỉ cần loại bỏ hai dòng trước

        athletes_data_dict = {
            'forename': fastest_athletes_sorted.iloc[0].loc["forename"],
            'surname': fastest_athletes_sorted.iloc[0].loc["surname"],
            'time': fastest_athletes_sorted.iloc[0].loc[distance]
            }
2 và chỉ sử dụng trực tiếp
def find_fastest_athletes[df, distance, gender, ages]:
    all_ages = {}
    df_gender = df.loc[df["gender"] == gender]
    for age in ages:
        df_age = df_gender.loc[df_gender["age"] == age]
        fastest_athlete = df_age.loc[df_age[distance].idxmin[]]
        all_ages[age] = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
    return all_ages
0 [để lấy hàng thứ 0] và
def find_fastest_athletes[df, distance, gender, ages]:
    all_ages = {}
    df_gender = df.loc[df["gender"] == gender]
    for age in ages:
        df_age = df_gender.loc[df_gender["age"] == age]
        fastest_athlete = df_age.loc[df_age[distance].idxmin[]]
        all_ages[age] = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
    return all_ages
1 [để lấy cột bạn muốn theo tên] trên
def find_fastest_athletes[df, distance, gender, ages]:
    all_ages = {}
    df_gender = df.loc[df["gender"] == gender]
    for age in ages:
        df_age = df_gender.loc[df_gender["age"] == age]
        fastest_athlete = df_age.loc[df_age[distance].idxmin[]]
        all_ages[age] = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
    return all_ages
2 khi nhận các giá trị cho
        athletes_data_dict = {
            'forename': fastest_athletes_sorted.iloc[0].loc["forename"],
            'surname': fastest_athletes_sorted.iloc[0].loc["surname"],
            'time': fastest_athletes_sorted.iloc[0].loc[distance]
            }
2. Vì vậy, nó sẽ trông như thế này

        athletes_data_dict = {
            'forename': fastest_athletes_sorted.iloc[0].loc["forename"],
            'surname': fastest_athletes_sorted.iloc[0].loc["surname"],
            'time': fastest_athletes_sorted.iloc[0].loc[distance]
            }

Tuy nhiên, chúng ta có thể làm cho việc này trở nên đơn giản hơn [và nhanh hơn], bằng cách loại bỏ hoàn toàn dòng

def find_fastest_athletes[df, distance, gender, ages]:
    all_ages = {}
    df_gender = df.loc[df["gender"] == gender]
    for age in ages:
        df_age = df_gender.loc[df_gender["age"] == age]
        fastest_athlete = df_age.loc[df_age[distance].idxmin[]]
        all_ages[age] = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
    return all_ages
2 và sử dụng
def find_fastest_athletes[df, distance, gender, ages]:
    all_ages = {}
    df_gender = df.loc[df["gender"] == gender]
    for age in ages:
        df_age = df_gender.loc[df_gender["age"] == age]
        fastest_athlete = df_age.loc[df_age[distance].idxmin[]]
        all_ages[age] = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
    return all_ages
5 để trực tiếp lấy hàng có thời gian tối thiểu trên cột đã chỉ định

        fastest_athlete = fastest_athletes.loc[fastest_athletes[distance].idxmin[]]
        athletes_data_dict = {
            'forename': fastest_athlete.loc["forename"],
            'surname': fastest_athlete.loc["surname"],
            'time': fastest_athlete.loc[distance]
            }

Tuy nhiên, chúng ta vẫn có thể làm tốt hơn. Chúng tôi đang xây dựng từ điển theo cách thủ công từ DataFrame đã có các cột và giá trị mà chúng tôi cần. Thay vì dòng

def find_fastest_athletes[df, distance, gender, ages]:
    all_ages = {}
    df_gender = df.loc[df["gender"] == gender]
    for age in ages:
        df_age = df_gender.loc[df_gender["age"] == age]
        fastest_athlete = df_age.loc[df_age[distance].idxmin[]]
        all_ages[age] = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
    return all_ages
6 trước đó, chúng ta có thể sử dụng phương thức
def find_fastest_athletes[df, distance, gender, ages]:
    all_ages = {}
    df_gender = df.loc[df["gender"] == gender]
    for age in ages:
        df_age = df_gender.loc[df_gender["age"] == age]
        fastest_athlete = df_age.loc[df_age[distance].idxmin[]]
        all_ages[age] = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
    return all_ages
7 của Pandas và một chút thay thế tên cột

        athletes_data_dict = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]

Tuy nhiên, chúng ta vẫn có thể làm tốt hơn. Chúng tôi chỉ có thể lọc các vận động viên theo giới tính một lần, thay vì mỗi vòng lặp, vì đó là một hằng số trong toàn hàm. Hơn nữa,

def find_fastest_athletes[df, distance, gender, ages]:
    all_ages = {}
    df_gender = df.loc[df["gender"] == gender]
    for age in ages:
        df_age = df_gender.loc[df_gender["age"] == age]
        fastest_athlete = df_age.loc[df_age[distance].idxmin[]]
        all_ages[age] = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
    return all_ages
8 được chuyển vào hàm, nhưng nó không bao giờ được sử dụng; . Vì vậy, bây giờ, đối với chức năng của chúng tôi, chúng tôi có

def find_fastest_athletes[df, distance, gender, ages]:
    all_ages = {}
    df_gender = df.loc[df["gender"] == gender]
    for age in ages:
        df_age = df_gender.loc[df_gender["age"] == age]
        fastest_athlete = df_age.loc[df_age[distance].idxmin[]]
        all_ages[age] = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
    return all_ages

và lời kêu gọi của chúng tôi,

    print[find_fastest_athletes[df, '100m', 'F', range[0, 17]]]

Tuy nhiên, ở đây, cuối cùng chúng ta cũng đến được vòng tròn đầy đủ. Chúng tôi có thể làm cho mã còn lại của mình đơn giản và nhanh hơn nhiều bằng cách hoàn toàn không sử dụng vòng lặp for. Thay vào đó, mặc dù chúng ta có thể sử dụng hàm

def find_fastest_athletes[df, distance, gender, ages]:
    all_ages = {}
    df_gender = df.loc[df["gender"] == gender]
    for age in ages:
        df_age = df_gender.loc[df_gender["age"] == age]
        fastest_athlete = df_age.loc[df_age[distance].idxmin[]]
        all_ages[age] = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
    return all_ages
9 của Pandas để nhóm theo độ tuổi và tìm ra những người chạy nhanh nhất trong mỗi nhóm, nhưng việc sử dụng một hàm bạn đã làm trước đây thậm chí còn đơn giản hơn—
    print[find_fastest_athletes[df, '100m', 'F', range[0, 17]]]
0. Tất cả những gì chúng ta cần làm là chọn các cột có độ tuổi và giới tính mà chúng ta muốn, sắp xếp các giá trị theo cột
        athletes_data_dict = fastest_athlete[
            ["forename", "surname", distance]].rename[{distance: "times"}].to_dict[]
1 đã chỉ định, loại bỏ các cột trùng lặp có cùng độ tuổi [i. e. những người có thời gian cao hơn so với người chạy hàng đầu], đặt chỉ mục và sắp xếp theo nó, cuối cùng chuyển đổi thành một lệnh như chúng tôi đã làm trước đây, đặt hướng để tạo định dạng bạn muốn. Điều này giúp chúng tôi

def find_fastest_athletes[df, distance, gender, ages]:
    df_byage = df.loc[[df["gender"] == gender] & df["age"].isin[ages]].sort_values[
        distance].drop_duplicates["age"].set_index["age"].sort_index[]
    return df_byage[["forename", "surname", distance]].rename[
        columns={distance: "times"}].to_dict[orient="index"]

Điều này cuối cùng chỉ có 4 dòng thay vì 13 dòng của chức năng ban đầu [đã sửa], chạy nhanh hơn khoảng 5 lần, xử lý khéo léo các trường hợp không có người chạy ở độ tuổi cụ thể và mạnh mẽ hơn nhiều đối với các vấn đề khác nhau được đề cập ở trên

Ngoài ra còn có một số điều khác bạn có thể cải thiện ở đây. Mã đang trộn các mức thụt lề, với bốn khoảng trắng ở một số khu vực và hai khoảng trắng ở những khu vực khác, điều này có thể rất khó hiểu và do đó rất không được khuyến khích. thay vào đó, tôi khuyên bạn chỉ nên sử dụng bốn khoảng trắng ở mọi nơi, đây là tiêu chuẩn trong Python. Trong

    print[find_fastest_athletes[df, '100m', 'F', range[0, 17]]]
2,
    print[find_fastest_athletes[df, '100m', 'F', range[0, 17]]]
3 là không cần thiết, vì trong Python, các hàm luôn trả về ngầm định sau khi phần thân của chúng hoàn thành.
    print[find_fastest_athletes[df, '100m', 'F', range[0, 17]]]
4 cũng vậy, vì Pandas đã chuyển đổi cột thành số float khi đọc từ CSV do nó chứa các giá trị số không nguyên

Cuối cùng, khi chúng ta kết hợp tất cả lại với nhau, mã cố định và đơn giản hóa tương đương với mã của bạn ở trên [với

    print[find_fastest_athletes[df, '100m', 'F', range[0, 17]]]
5 là hằng số cấp cao nhất có đường dẫn đến tệp] tạo ra kết quả mong muốn của bạn là

Bạn có thể lặp qua DataFrame không?

Vòng lặp khung dữ liệu [lặp lại] với câu lệnh for. Bạn có thể lặp qua khung dữ liệu gấu trúc, cho từng hàng cột .

Làm cách nào để tạo DataFrame mới từ DataFrame hiện có trong gấu trúc?

Gấu trúc. Cách tạo Khung dữ liệu mới từ Khung dữ liệu hiện có .
Phương pháp 1. Tạo Khung dữ liệu mới bằng nhiều cột từ Khung dữ liệu cũ new_df = old_df[['col1','col2']]. .
Phương pháp 2. Tạo Khung dữ liệu mới bằng một cột từ Khung dữ liệu cũ new_df = old_df[['col1']]

Bạn có thể có một từ điển Dataframes?

Để tạo khung dữ liệu, trước tiên bạn phải tạo từ điển . Từ điển là danh sách các giá trị được liên kết với các khóa. Các khóa được phân tách khỏi các giá trị của chúng bằng dấu hai chấm và dấu ngoặc như hình bên dưới. Trong trường hợp này, các khóa từ điển sẽ trở thành tên cột cho DataFrame.

Chủ Đề