【LeetCode】30 天 Pandas 挑战

一、笔记

1.对某列进行筛选

df[(df[column1]条件1) | (df[column2]条件2) & (df[column3]条件3)][[columns]]

真题:

  • (一)条件筛选——1.大的国家
  • (一)条件筛选——2.可回收且低脂的产品
  • (一)条件筛选——4.文章浏览1
  • (四)数据统计——16.富有客户的数量
  • (四)数据统计——18.按分类统计薪水
  • (六)数据合并——26.合作过至少三次的演员和导演

2.某列是否包含/不包含另一列

df1[~df1[column1].isin(df2[column2])][[columns]]

真题:

  • (一)条件筛选——3.从不订购的客户
  • (六)数据合并——29.至少有5名直接下属的经理
  • (六)数据合并——30.销售员

3.列表重命名

# 方式一
df.rename(columns={old_column:new_column})
# 方式二
df.columns = [columns]

4.某列值相关属性

4.1 字符串

# 字符串长度
df[column].str.len()
# 使得只有第一个字符是大写的,其余都是小写的
df[column].str.capitalize()
# 字符串正则表达式
df[column].str.match(正则表达式)
# 字符串包含
df[column].str.contains(正则表达式)

真题:

  • (二)字符串函数——5.无效的推文
  • (二)字符串函数——7.修复表中的名字
  • (二)字符串函数——8.查找拥有有效邮箱的用户
  • (二)字符串函数——9.患某种疾病的患者

4.2 函数

# 以某个字符开头
df[column].startswith(字符)
# 列中前M个最大值的Series,Series中的最后N个元素,转成dataframe
df[column].nlargest(M).tail(N).to_frame()
# 最大值
df[column].max()
# 排名
df[column].rank(method="dense",ascending=False)
# 去除空
df.dropna()
# 求和
df[column].sum()
# 最小值
df[column].min()

真题:

  • (二)字符串函数——6.计算特殊奖金
  • (三)数据操作——10.第N高的薪水
  • (三)数据操作——11.第二高的薪水
  • (三)数据操作——12.部门工资最高的员工
  • (三)数据操作——13.分数排名
  • (三)数据操作——15.每个产品在不同商店的价格
  • (五)数据分组——19.查找每个员工花费的总时间
  • (五)数据分组——20.游戏玩法分析1
  • (五)数据分组——23.定单最多的客户
  • (六)数据合并——28.学生们参加各科测试的次数

5.对行/列进行操作

# 行
df.apply(操作, axis=1)
# 列
df.apply(操作, axis=0)

真题:

  • (二)字符串函数——6.计算特殊奖金
  • (三)数据操作——12.部门工资最高的员工
  • (五)数据分组——24.按日期分组销售产品

6.去重

df.drop_duplicates([columns])
df.drop_duplicates(subset=column,keep="first",inplace=True)
df.nunique()

真题:

  • (三)数据操作——11.第二高的薪水
  • (三)数据操作——14.删除重复的电子邮箱
  • (四)数据统计——16.富有客户的数量
  • (五)数据分组——21.每位教师所教授的科目种类
  • (五)数据分组——24.按日期分组销售产品

7.关联

# join
df1.set_index(column1).join(df2.set_index(column2), how="left")
# merge
df1.merge(df2, on=[columns], how='left', indicator=True)
## 笛卡尔积
df1.assign(key=1).merge(df2.assign(key=1), on='key').drop('key', axis=1)

真题:

  • (三)数据操作——12.部门工资最高的员工
  • (五)数据分组——24.按日期分组销售产品
  • (五)数据分组——25.每天的领导和合伙人
  • (六)数据合并——27.使用唯一标识码替换员工ID
  • (六)数据合并——28.学生们参加各科测试的次数

8.排序

df.sort_values([column], ascending=False).reset_index(drop=True)

真题:

  • (三)数据操作——13.分数排名
  • (三)数据操作——14.删除重复的电子邮箱
  • (五)数据分组——24.按日期分组销售产品

9.合并

pd.concat([df_1,df_2,df_3], axis=0, ignore_index=True)

真题:

  • (三)数据操作——15.每个产品在不同商店的价格

10.分组

df.groupby(column).reset_index(name=new_column)
# 分组计数
df.groupby([column]).size().reset_index(name=new_column)
# 分组去重计数
df.groupby([column1])[column2].nunique().reset_index(name=new_column)

真题:

  • (五)数据分组——21.每位教师所教授的科目种类
  • (五)数据分组——22.超过5名学生课
  • (五)数据分组——23.定单最多的客户
  • (五)数据分组——24.按日期分组销售产品
  • (五)数据分组——25.每天的领导和合伙人
  • (六)数据合并——26.合作过至少三次的演员和导演
  • (六)数据合并——29.至少有5名直接下属的经理

二、真题

(一)条件筛选

1.大的国家

如果一个国家满足下述两个条件之一,则认为该国是大国:面积至少为300万平方公里(即3000000km2),或者人口至少为 2500万(即25000000)
编写解决方案找出大国的国家名称、人口和面积。按 任意顺序返回结果表。

import pandas as pd

def big_countries(world: pd.DataFrame) -> pd.DataFrame:
    return world[(world["area"] >= 3000000) | (world["population"] >= 25000000)][["name","population","area"]]

2.可回收且低脂的产品

编写解决方案找出既是低脂又是可回收的产品编号。返回结果 无顺序要求 。

import pandas as pd

def find_products(products: pd.DataFrame) -> pd.DataFrame:
    return products[(products["low_fats"] == "Y") & (products["recyclable"] == "Y")][["product_id"]]

3.从不订购的客户

找出所有从不点任何东西的顾客。以任意顺序返回结果表。

import pandas as pd

def find_customers(customers: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame:
    return customers[~customers["id"].isin(orders["customerId"])][["name"]].rename(columns={"name":"Customers"})

4.文章浏览1

请查询出所有浏览过自己文章的作者,结果按照 id 升序排列。

import pandas as pd

def article_views(views: pd.DataFrame) -> pd.DataFrame:
    return views[views["author_id"] == views["viewer_id"]][["viewer_id"]].rename(columns={"viewer_id":"id"}).drop_duplicates().sort_values(by=["id"])

5.无效的推文

查询所有无效推文的编号(ID)。当推文内容中的字符数严格大于 15 时,该推文是无效的。以任意顺序返回结果表。

import pandas as pd

def invalid_tweets(tweets: pd.DataFrame) -> pd.DataFrame:
    return tweets[tweets["content"].str.len() > 15][["tweet_id"]]

6.计算特殊奖金

编写解决方案,计算每个雇员的奖金。如果一个雇员的 id 是 奇数 并且他的名字不是以 ‘M’ 开头,那么他的奖金是他工资的 100% ,否则奖金为 0 。返回的结果按照 employee_id 排序。

import pandas as pd

def calculate_nonus(row):
    if row["employee_id"] % 2 == 1 and not row["name"].startswith("M"):
        return row["salary"]
    else:
        return 0

def calculate_special_bonus(employees: pd.DataFrame) -> pd.DataFrame:
    employees["salary"] = employees.apply(calculate_nonus, axis=1)
    return employees[["employee_id","salary"]].rename(columns={"salary":"bonus"}).sort_values(by="employee_id")

7.修复表中的名字

编写解决方案,修复名字,使得只有第一个字符是大写的,其余都是小写的。返回按 user_id 排序的结果表。

import pandas as pd

def fix_names(users: pd.DataFrame) -> pd.DataFrame:
    users["name"] = users["name"].str.capitalize()

    return users.sort_values(by=["user_id"])

8.查找拥有有效邮箱的用户

编写一个解决方案,以查找具有有效电子邮件的用户。一个有效的电子邮件具有前缀名称和域,其中: 前缀 名称是一个字符串,可以包含字母(大写或小写),数字,下划线 ‘_’ ,点 ‘.’ 和/或破折号 ‘-’ 。前缀名称 必须 以字母开头。域 为 ‘@leetcode.com’ 。以任何顺序返回结果表。

import pandas as pd

def valid_emails(users: pd.DataFrame) -> pd.DataFrame:
    return users[users["mail"].str.match(r"^[a-zA-Z][a-zA-Z0-9_.\-]*@leetcode\.com$")]

9.患某种疾病的患者

查询患有 I 类糖尿病的患者 ID (patient_id)、患者姓名(patient_name)以及其患有的所有疾病代码(conditions)。I 类糖尿病的代码总是包含前缀 DIAB1 。按 任意顺序 返回结果表。

import pandas as pd

def find_patients(patients: pd.DataFrame) -> pd.DataFrame:
    return patients[patients["conditions"].str.contains(r'\bDIAB1\w*', regex=True)]

10.第N高的薪水

查询 Employee 表中第 n 高的工资。如果没有第 n 个最高工资,查询结果应该为 null 。

import pandas as pd

def nth_highest_salary(employee: pd.DataFrame, N: int) -> pd.DataFrame:
    employee = employee.drop_duplicates('salary')
    return employee['salary'].nlargest(N).tail(1).to_frame() if employee.shape[0]>=N else pd.DataFrame()

11.第二高的薪水

查询并返回 Employee 表中第二高的薪水 。如果不存在第二高的薪水,查询应该返回 null(Pandas 则返回 None) 。

import pandas as pd

def second_highest_salary(employee: pd.DataFrame) -> pd.DataFrame:
    employee = employee.drop_duplicates('salary')
    return employee["salary"].nlargest(2).tail(1).to_frame().rename(columns={"salary":"SecondHighestSalary"}) if employee.shape[0]>=2 else pd.DataFrame([None], columns=["SecondHighestSalary"])

12.部门工资最高的员工

查找出每个部门中薪资最高的员工。按 任意顺序 返回结果表。

import pandas as pd

def department_highest_salary(employee: pd.DataFrame, department: pd.DataFrame) -> pd.DataFrame:
    df = employee.set_index("departmentId").join(department.rename(columns={"name":"Department"}).set_index("id"), how="left")
    return df.groupby("Department").apply(lambda x:x[x["salary"]==x["salary"].max()])[["Department","name","salary"]].rename(columns={"name":"Employee","salary":"Salary"})

13.分数排名

查询并对分数进行排序。排名按以下规则计算:分数应按从高到低排列。如果两个分数相等,那么两个分数的排名应该相同。在排名相同的分数后,排名数应该是下一个连续的整数。换句话说,排名之间不应该有空缺的数字。按 score 降序返回结果表。

import pandas as pd

def order_scores(scores: pd.DataFrame) -> pd.DataFrame:
    scores = scores.sort_values(["score"], ascending=False).reset_index(drop=True)
    scores["rank"] = scores["score"].rank(method="dense",ascending=False)
    return scores[["score","rank"]]

14.删除重复的电子邮箱

编写解决方案 删除 所有重复的电子邮件,只保留一个具有最小 id 的唯一电子邮件。(对于 SQL 用户,请注意你应该编写一个 DELETE 语句而不是 SELECT 语句。)(对于 Pandas 用户,请注意你应该直接修改 Person 表。)运行脚本后,显示的答案是 Person 表。驱动程序将首先编译并运行您的代码片段,然后再显示 Person 表。Person 表的最终顺序 无关紧要 。

import pandas as pd

# Modify Person in place
def delete_duplicate_emails(person: pd.DataFrame) -> None:
    if len(person):
        person.sort_values(by=["id"], inplace=True)
        return person.drop_duplicates(subset='email',keep="first",inplace=True) 
    else:
        return None

15.每个产品在不同商店的价格

请你重构 Products 表,查询每个产品在不同商店的价格,使得输出的格式变为(product_id, store, price) 。如果这一产品在商店里没有出售,则不输出这一行。输出结果表中的 顺序不作要求 。

import pandas as pd

def rearrange_products_table(products: pd.DataFrame) -> pd.DataFrame:
    df_1 = products[["product_id", "store1"]].rename(columns={"store1":"price"}).dropna()
    df_1["store"] = "store1"
    df_2 = products[["product_id", "store2"]].rename(columns={"store2":"price"}).dropna()
    df_2["store"] = "store2"
    df_3 = products[["product_id", "store3"]].rename(columns={"store3":"price"}).dropna()
    df_3["store"] = "store3"
    df = pd.concat([df_1,df_2,df_3], axis=0, ignore_index=True)[["product_id","store","price"]]
    return df

16.富有客户的数量

编写解决方案找出 至少有一个 订单的金额 严格大于 500 的客户的数量。

import pandas as pd

def count_rich_customers(store: pd.DataFrame) -> pd.DataFrame:
    return pd.DataFrame({"rich_count": store[store["amount"] > 500][["customer_id"]].nunique()})

17.即时食物配送

如果顾客期望的配送日期和下单日期相同,则该订单称为 「即时订单」,否则称为「计划订单」。编写解决方案统计即时订单所占的百分比, 保留两位小数。

import pandas as pd

def food_delivery(delivery: pd.DataFrame) -> pd.DataFrame:
    return pd.DataFrame({"immediate_percentage": [round(len(delivery[delivery["order_date"]==delivery["customer_pref_delivery_date"]])/len(delivery)*100, 2)]})

18.按分类统计薪水

查询每个工资类别的银行账户数量。 工资类别如下:
“Low Salary”:所有工资 严格低于 20000 美元。
“Average Salary”: 包含 范围内的所有工资 [$20000, $50000] 。
“High Salary”:所有工资 严格大于 50000 美元。
结果表 必须 包含所有三个类别。 如果某个类别中没有帐户,则报告 0 。按 任意顺序 返回结果表。

import pandas as pd

def count_salary_categories(accounts: pd.DataFrame) -> pd.DataFrame:
    return pd.DataFrame({"category":["Low Salary","Average Salary","High Salary"],"accounts_count":[len(accounts[accounts["income"]<20000]),len(accounts[(accounts["income"]>=20000) & (accounts["income"]<=50000)]),len(accounts[accounts["income"]>50000])]})

19.查找每个员工花费的总时间

计算每位员工每天在办公室花费的总时间(以分钟为单位)。 请注意,在一天之内,同一员工是可以多次进入和离开办公室的。 在办公室里一次进出所花费的时间为out_time 减去 in_time。返回结果表单的顺序无要求。

import pandas as pd

def total_time(employees: pd.DataFrame) -> pd.DataFrame:
    employees["difference"] = employees["out_time"] - employees["in_time"]
    return employees.groupby(["emp_id","event_day"])["difference"].sum().reset_index()[["event_day","emp_id","difference"]].rename(columns={"event_day":"day","difference":"total_time"})

20.游戏玩法分析1

查询每位玩家 第一次登陆平台的日期。

import pandas as pd

def game_analysis(activity: pd.DataFrame) -> pd.DataFrame:
    return activity.groupby("player_id")["event_date"].min().reset_index().rename(columns={"event_date":"first_login"})

21.每位教师所教授的科目种类

import pandas as pd

def count_unique_subjects(teacher: pd.DataFrame) -> pd.DataFrame:
    return teacher.groupby('teacher_id')['subject_id'].nunique().reset_index(name='cnt')

22.超过5名学生课

查询 至少有5个学生 的所有班级。以 任意顺序 返回结果表。

import pandas as pd

def find_classes(courses: pd.DataFrame) -> pd.DataFrame:
    courses = courses.groupby(["class"]).size().reset_index(name='count')
    return courses[courses["count"]>=5][["class"]]

23.定单最多的客户

查找下了 最多订单 的客户的 customer_number 。测试用例生成后, 恰好有一个客户 比任何其他客户下了更多的订单。

import pandas as pd

def largest_orders(orders: pd.DataFrame) -> pd.DataFrame:
    orders = orders.groupby(["customer_number"]).size().reset_index(name="count")
    return orders[orders["count"]==orders["count"].max()][["customer_number"]]

24.按日期分组销售产品

编写解决方案找出每个日期、销售的不同产品的数量及其名称。每个日期的销售产品名称应按词典序排列。返回按 sell_date 排序的结果表。

import pandas as pd

def categorize_products(activities: pd.DataFrame) -> pd.DataFrame:
    activities = activities.drop_duplicates().sort_values(by='product')
    activities_num_sold = activities.groupby('sell_date').size().reset_index(name='num_sold')
    activities_products = activities.groupby("sell_date")["product"].apply(','.join).reset_index(name="products")
    return activities_num_sold.set_index("sell_date").join(activities_products.set_index("sell_date"), how="left").reset_index()

25.每天的领导和合伙人

对于每一个 date_id 和 make_name,找出 不同 的 lead_id 以及 不同 的 partner_id 的数量。按 任意顺序 返回结果表。

import pandas as pd

def daily_leads_and_partners(daily_sales: pd.DataFrame) -> pd.DataFrame:
    daily_sales_unique_leads = daily_sales.groupby(["date_id","make_name"])['lead_id'].nunique().reset_index(name='unique_leads')
    daily_sales_unique_partners = daily_sales.groupby(["date_id","make_name"])['partner_id'].nunique().reset_index(name='unique_partners')
    return daily_sales_unique_leads.set_index(["date_id","make_name"]).join(daily_sales_unique_partners.set_index(["date_id","make_name"]), how='left').reset_index()

26.合作过至少三次的演员和导演

编写解决方案找出合作过至少三次的演员和导演的 id 对 (actor_id, director_id)

import pandas as pd

def actors_and_directors(actor_director: pd.DataFrame) -> pd.DataFrame:
    actor_director = actor_director.groupby(["actor_id","director_id"]).size().reset_index(name="cnt")
    return actor_director[actor_director["cnt"]>=3][["actor_id","director_id"]]

27.使用唯一标识码替换员工ID

展示每位用户的 唯一标识码(unique ID );如果某位员工没有唯一标识码,使用 null 填充即可。你可以以 任意 顺序返回结果表。

import pandas as pd

def replace_employee_id(employees: pd.DataFrame, employee_uni: pd.DataFrame) -> pd.DataFrame:
    return employee_uni.set_index('id').join(employees.set_index('id'), how='right').reset_index()[["unique_id","name"]]

28.学生们参加各科测试的次数

查询出每个学生参加每一门科目测试的次数,结果按 student_id 和 subject_name 排序。

import pandas as pd
import numpy as np

def students_and_examinations(students: pd.DataFrame, subjects: pd.DataFrame, examinations: pd.DataFrame) -> pd.DataFrame:
    students = students.assign(key=1).merge(subjects.assign(key=1), on='key').drop('key', axis=1)
    students = students.merge(examinations, on=['student_id', 'subject_name'], how='left', indicator=True)
    students['attended_exams'] = (students['_merge'] == 'both').astype(int)
    return students.groupby(['student_id', 'student_name', 'subject_name'])['attended_exams'].sum().reset_index()

29.至少有5名直接下属的经理

查询至少有5名直接下属的经理 。以 任意顺序 返回结果表。

import pandas as pd

def find_managers(employee: pd.DataFrame) -> pd.DataFrame:
    employee_cnt = employee.groupby(["managerId"]).size().reset_index(name="cnt")
    return employee[employee["id"].isin(employee_cnt[employee_cnt["cnt"]>=5]["managerId"])][["name"]]

30.销售员

编写解决方案,找出没有任何与名为 “RED” 的公司相关的订单的所有销售人员的姓名。以 任意顺序 返回结果表。

import pandas as pd

def sales_person(sales_person: pd.DataFrame, company: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame:
    return sales_person[~sales_person["sales_id"].isin(orders[orders["com_id"].isin(company[company["name"]=="RED"]["com_id"])][["sales_id"]]["sales_id"])][["name"]]

你可能感兴趣的:(LeetCode,leetcode,pandas,大数据)