30天pandas挑战
大的国家
挑选出符合要求的行
def big_countries(world: pd.DataFrame) -> pd.DataFrame:
df = world[(world['area'] >= 3000000) | (world['population'] >= 25000000)]
return df[['name','population','area']]
在Pandas中,当你使用条件过滤时,应该使用
&
而不是and
。这是因为Pandas的布尔索引是基于位运算的,&
可以用于连接多个条件,并且会逐元素地评估这些条件。
可回收且低脂的产品
挑选出符合要求的行
def find_products(products: pd.DataFrame) -> pd.DataFrame:
return products[(products['low_fats'] == 'Y') & (products['recyclable'] == 'Y')][['product_id']]
从不订购的客户
使用isin在两张表中联合查找
题目:
Customers
表:
+-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | name | varchar | +-------------+---------+ 在 SQL 中,id 是该表的主键。 该表的每一行都表示客户的 ID 和名称。
Orders
表:
+-------------+------+ | Column Name | Type | +-------------+------+ | id | int | | customerId | int | +-------------+------+ 在 SQL 中,id 是该表的主键。 customerId 是 Customers 表中 ID 的外键( Pandas 中的连接键)。 该表的每一行都表示订单的 ID 和订购该订单的客户的 ID。
找出所有从不点任何东西的顾客。
以 任意顺序 返回结果表。
结果格式如下所示。
示例 1:
输入: Customers table: +----+-------+ | id | name | +----+-------+ | 1 | Joe | | 2 | Henry | | 3 | Sam | | 4 | Max | +----+-------+ Orders table: +----+------------+ | id | customerId | +----+------------+ | 1 | 3 | | 2 | 1 | +----+------------+ 输出: +-----------+ | Customers | +-----------+ | Henry | | Max | +-----------+
#方法 1:使用排除条件过滤数据
import pandas as pd
def find_customers(customers: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame:
# 选择 orders['customerId'] 中 'id' 不存在的行。
df = customers[~customers['id'].isin(orders['customerId'])]
# 创建一个只包含 name 列的数据框架
# 并将列 name 重命名为 Customers。
df = df[['name']].rename(columns={'name': 'Customers'})
return df
#方法二:使用左连接
import pandas as pd
def find_customers(customers: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame:
df = customers.merge(orders, left_on='id', right_on='customerId', how='left')
df = df[df['customerId'].isna()]
df = df[['name']].rename(columns={'name': 'Customers'})
return df
文章浏览I
请查询出所有浏览过自己文章的作者
结果按照 id
升序排列。
查询结果的格式如下所示:
示例 1:
输入: Views 表: +------------+-----------+-----------+------------+ | article_id | author_id | viewer_id | view_date | +------------+-----------+-----------+------------+ | 1 | 3 | 5 | 2019-08-01 | | 1 | 3 | 6 | 2019-08-02 | | 2 | 7 | 7 | 2019-08-01 | | 2 | 7 | 6 | 2019-08-02 | | 4 | 7 | 1 | 2019-07-22 | | 3 | 4 | 4 | 2019-07-21 | | 3 | 4 | 4 | 2019-07-21 | +------------+-----------+-----------+------------+ 输出: +------+ | id | +------+ | 4 | | 7 | +------+
import pandas as pd
def article_views(views: pd.DataFrame) -> pd.DataFrame:
df = views[ views['author_id'] == views['viewer_id'] ]
df.drop_duplicates(subset = ['author_id'],inplace = True)
df.rename(columns = {'author_id':'id'},inplace = True)
df = df[['id']]
df.sort_values(by = 'id',inplace = True)
return df
无效的推文
查询所有无效推文的编号(ID)。当推文内容中的字符数严格大于 15
时,该推文是无效的。
import pandas as pd
def invalid_tweets(tweets: pd.DataFrame) -> pd.DataFrame:
return tweets[tweets['content'].str.len() > 15][['tweet_id']]
计算特殊奖金
编写解决方案,计算每个雇员的奖金。如果一个雇员的 id 是 奇数 并且他的名字不是以 'M'
开头,那么他的奖金是他工资的 100%
,否则奖金为 0
。
返回的结果按照 employee_id
排序。
import pandas as pd
def calculate_special_bonus(employees: pd.DataFrame) -> pd.DataFrame:
df = employees
df['bonus'] = 0
bonusIf = (df['employee_id'] % 2 ==1 ) & (df['name'].str[0] != 'M' )
df['bonus'][bonusIf] = df['salary']
df = df.sort_values(by = 'employee_id')
return df[['employee_id','bonus']]
#官方题解,使用了apply
import pandas as pd
def calculate_special_bonus(employees: pd.DataFrame) -> pd.DataFrame:
employees['bonus'] = employees.apply(
lambda x: x['salary'] if x['employee_id'] % 2 and not x['name'].startswith('M') else 0,
axis=1
)
df = employees[['employee_id', 'bonus']].sort_values('employee_id')
return df
修复表中的名字
编写解决方案,修复名字,使得只有第一个字符是大写的,其余都是小写的。
返回按 user_id
排序的结果表。
import pandas as pd
def fix_names(users: pd.DataFrame) -> pd.DataFrame:
users['name'] = users['name'].apply(lambda x: x[0].upper() + x[1:].lower())
return users.sort_values(by = 'user_id')
查找拥有有效邮箱的用户
编写一个解决方案,以查找具有有效电子邮件的用户。
一个有效的电子邮件具有前缀名称和域,其中:
- 前缀 名称是一个字符串,可以包含字母(大写或小写),数字,下划线
'_'
,点'.'
和/或破折号'-'
。前缀名称 必须 以字母开头。 - 域 为
'@leetcode.com'
。
以任何顺序返回结果表。
正则表达式提供各种功能,以下是一些相关功能:
^:表示一个字符串或行的开头
[a-z]:表示一个字符范围,匹配从 a 到 z 的任何字符。
[0-9]:表示一个字符范围,匹配从 0 到 9 的任何字符。
[a-zA-Z]:这个变量匹配从 a 到 z 或 A 到 Z 的任何字符。请注意,你可以在方括号内指定的字符范围的数量没有限制,您可以添加想要匹配的其他字符或范围。
[^a-z]:这个变量匹配不在 a 到 z 范围内的任何字符。请注意,字符 ^ 用来否定字符范围,它在方括号内的含义与它的方括号外表示开始的含义不同。
[a-z]*:表示一个字符范围,匹配从 a 到 z 的任何字符 0 次或多次。
[a-z]+:表示一个字符范围,匹配从 a 到 z 的任何字符 1 次或多次。
.:匹配任意一个字符。
\.:表示句点字符。请注意,反斜杠用于转义句点字符,因为句点字符在正则表达式中具有特殊含义。还要注意,在许多语言中,你需要转义反斜杠本身,因此需要使用\\.。
$:表示一个字符串或行的结尾。
核心思想是将 name 列的第一个字符从其余字符分开,相应地改变它们的大小写,最后把他们拼回在一起。
import pandas as pd
def valid_emails(users: pd.DataFrame) -> pd.DataFrame:
# 注意我们如何使用原始字符串(在前面放一个‘r’)来避免必须转义反斜杠
# 还要注意,我们对`@`字符进行了转义,因为它在某些正则表达式中具有特殊意义
return users[users["mail"].str.match(r"^[a-zA-Z][a-zA-Z0-9_.-]*\@leetcode\.com$")]
患有某种疾病的患者
查询患有 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',regex = True)]
\b
: 这是一个单词边界匹配符。它用于匹配一个单词的开始或结束位置。在正则表达式中,单词由字母、数字或下划线组成。使用\b
可以确保"DIAB1"作为一个独立的单词被匹配,而不是其他单词的一部分,比如"DIAB123"或"DIAB1A"。
删除重复的电子邮箱
编写解决方案 删除 所有重复的电子邮件,只保留一个具有最小 id
的唯一电子邮件。
输入: Person 表: +----+------------------+ | id | email | +----+------------------+ | 1 | john@example.com | | 2 | bob@example.com | | 3 | john@example.com | +----+------------------+ 输出: +----+------------------+ | id | email | +----+------------------+ | 1 | john@example.com | | 2 | bob@example.com | +----+------------------+ 解释: john@example.com重复两次。我们保留最小的Id = 1。
import pandas as pd
def delete_duplicate_emails(person: pd.DataFrame) -> None:
person.sort_values(by = 'id',ascending = True,inplace = True)
person.drop_duplicates(subset = ['email'],keep = 'first',inplace = True)
return
每个产品在不同商店的价格
请你重构 Products
表,查询每个产品在不同商店的价格,使得输出的格式变为(product_id, store, price)
。如果这一产品在商店里没有出售,则不输出这一行。
输出结果表中的 顺序不作要求 。
查询输出格式请参考下面示例。
示例 1:
输入: Products table: +------------+--------+--------+--------+ | product_id | store1 | store2 | store3 | +------------+--------+--------+--------+ | 0 | 95 | 100 | 105 | | 1 | 70 | null | 80 | +------------+--------+--------+--------+ 输出: +------------+--------+-------+ | product_id | store | price | +------------+--------+-------+ | 0 | store1 | 95 | | 0 | store2 | 100 | | 0 | store3 | 105 | | 1 | store1 | 70 | | 1 | store3 | 80 | +------------+--------+-------+ 解释: 产品 0 在 store1、store2、store3 的价格分别为 95、100、105。 产品 1 在 store1、store3 的价格分别为 70、80。在 store2 无法买到。
import pandas as pd
def rearrange_products_table(products: pd.DataFrame) -> pd.DataFrame:
products = products.melt(
id_vars = ['product_id'],
value_vars = ['store1','store2','store3'],
var_name = 'store',
value_name = 'price'
)
return products.dropna(subset = ['price'])
这个就是数据透视中的融合,把宽格式转化成长格式
分数排名
编写一个解决方案来查询分数的排名。排名按以下规则计算:
- 分数应按从高到低排列。
- 如果两个分数相等,那么两个分数的排名应该相同。
- 在排名相同的分数后,排名数应该是下一个连续的整数。换句话说,排名之间不应该有空缺的数字。
按 score
降序返回结果表。
查询结果格式如下所示。
示例 1:
输入: Scores 表: +----+-------+ | id | score | +----+-------+ | 1 | 3.50 | | 2 | 3.65 | | 3 | 4.00 | | 4 | 3.85 | | 5 | 4.00 | | 6 | 3.65 | +----+-------+ 输出: +-------+------+ | score | rank | +-------+------+ | 4.00 | 1 | | 4.00 | 1 | | 3.85 | 2 | | 3.65 | 3 | | 3.65 | 3 | | 3.50 | 4 | +-------+------+
import pandas as pd
def order_scores(scores: pd.DataFrame) -> pd.DataFrame:
scores['rank'] = scores['score'].rank(method = 'dense',ascending = False)
return scores[['score','rank']].sort_values(by = 'rank')
-
基本语法:
DataFrame.rank(method='average', axis=0, ascending=True, percentile=False, na_option='keep', method_deprecated=False) Series.rank(method='average', axis=0, ascending=True, percentile=False, na_option='keep', method_deprecated=False)
-
参数:
method
:指定排名的方法。常用的有 'average'(默认,相同值的元素共享排名,赋予平均排名)、'min'(相同值的元素共享排名,赋予最小排名)、'max'(相同值的元素共享排名,赋予最大排名)、'first'(按照值出现的顺序排名)、'dense'(类似于 'min' 方法,但是排名总是连续的,没有间隙)。axis
:指定沿着哪个轴进行排名,0 表示行(默认),1 表示列。ascending
:布尔值,指定是升序排名(True)还是降序排名(False)。percentile
:布尔值,如果为 True,则排名值为百分位数。na_option
:指定缺失值的处理方式,'keep'(默认,缺失值的排名为 NaN)、'top'(将缺失值排在前面)、'bottom'(将缺失值排在后面)。method_deprecated
:布尔值,用于向后兼容旧版本的方法参数。
这题就是要你用rank()的dense的,考并且只考了这个,算比较单一的小题
查找每个员工花费的总时间
计算每位员工每天在办公室花费的总时间(以分钟为单位)。 请注意,在一天之内,同一员工是可以多次进入和离开办公室的。 在办公室里一次进出所花费的时间为out_time 减去 in_time。
返回结果表单的顺序无要求。
查询结果的格式如下:
示例 1:
输入: Employees table: +--------+------------+---------+----------+ | emp_id | event_day | in_time | out_time | +--------+------------+---------+----------+ | 1 | 2020-11-28 | 4 | 32 | | 1 | 2020-11-28 | 55 | 200 | | 1 | 2020-12-03 | 1 | 42 | | 2 | 2020-11-28 | 3 | 33 | | 2 | 2020-12-09 | 47 | 74 | +--------+------------+---------+----------+ 输出: +------------+--------+------------+ | day | emp_id | total_time | +------------+--------+------------+ | 2020-11-28 | 1 | 173 | | 2020-11-28 | 2 | 30 | | 2020-12-03 | 1 | 41 | | 2020-12-09 | 2 | 27 | +------------+--------+------------+ 解释: 雇员 1 有三次进出: 有两次发生在 2020-11-28 花费的时间为 (32 - 4) + (200 - 55) = 173, 有一次发生在 2020-12-03 花费的时间为 (42 - 1) = 41。 雇员 2 有两次进出: 有一次发生在 2020-11-28 花费的时间为 (33 - 3) = 30, 有一次发生在 2020-12-09 花费的时间为 (74 - 47) = 27。
import pandas as pd
def total_time(employees: pd.DataFrame) -> pd.DataFrame:
employees['total_time'] = employees['out_time'] - employees['in_time']
df = employees.groupby(['emp_id','event_day'])[['total_time']].sum().reset_index()
df.rename(columns = {'event_day':'day'},inplace = True)
return df[['day','emp_id','total_time']]
- 很明显的groupby
- 在
pandas
中,groupby
操作后通常会返回一个聚合结果,这个结果是一个Series
对象,其中索引是分组键(在这个例子中是emp_id
和event_day
),数据是聚合函数(如sum
)的结果。当你使用reset_index()
方法时,它会将这些分组键从索引转换为 DataFrame 的列。
游戏玩法分析
查询每位玩家 第一次登录平台的日期。
查询结果的格式如下所示:
Activity 表: +-----------+-----------+------------+--------------+ | player_id | device_id | event_date | games_played | +-----------+-----------+------------+--------------+ | 1 | 2 | 2016-03-01 | 5 | | 1 | 2 | 2016-05-02 | 6 | | 2 | 3 | 2017-06-25 | 1 | | 3 | 1 | 2016-03-02 | 0 | | 3 | 4 | 2018-07-03 | 5 | +-----------+-----------+------------+--------------+ Result 表: +-----------+-------------+ | player_id | first_login | +-----------+-------------+ | 1 | 2016-03-01 | | 2 | 2017-06-25 | | 3 | 2016-03-02 | +-----------+-------------+
import pandas as pd
def game_analysis(activity: pd.DataFrame) -> pd.DataFrame:
activity.sort_values(by = ['player_id','event_date'],ascending = True,inplace = True)
activity.drop_duplicates(subset = ['player_id'],keep = 'first',inplace = True)
activity.rename(columns = {'event_date':'first_login'},inplace = True)
return activity[['player_id','first_login']]
这个题目现在肯定不是完全体,挺简单的
每位教师所教授的科目种类
查询每位老师在大学里教授的科目种类的数量。
以 任意顺序 返回结果表。
查询结果格式示例如下。
示例 1:
输入: Teacher 表: +------------+------------+---------+ | teacher_id | subject_id | dept_id | +------------+------------+---------+ | 1 | 2 | 3 | | 1 | 2 | 4 | | 1 | 3 | 3 | | 2 | 1 | 1 | | 2 | 2 | 1 | | 2 | 3 | 1 | | 2 | 4 | 1 | +------------+------------+---------+ 输出: +------------+-----+ | teacher_id | cnt | +------------+-----+ | 1 | 2 | | 2 | 4 | +------------+-----+ 解释: 教师 1: - 他在 3、4 系教科目 2。 - 他在 3 系教科目 3。 教师 2: - 他在 1 系教科目 1。 - 他在 1 系教科目 2。 - 他在 1 系教科目 3。 - 他在 1 系教科目 4。
import pandas as pd
def count_unique_subjects(teacher: pd.DataFrame) -> pd.DataFrame:
teacher.drop_duplicates(subset = ['teacher_id','subject_id'],keep = 'first',inplace = True)
teacher = teacher[['teacher_id','subject_id']]
df = teacher.groupby(['teacher_id']).count().reset_index()
return df.rename(columns = {'subject_id':'cnt'})
# 官方题解
import pandas as pd
def count_unique_subjects(teacher: pd.DataFrame) -> pd.DataFrame:
df = teacher.groupby(["teacher_id"])["subject_id"].nunique().reset_index()
df = df.rename({'subject_id': "cnt"}, axis=1)
return df
这个题目肯迪那个也是阉割版,期待一下完全体
另:官方题解用了nunique(),真不错
超过5名学生的课
查询 至少有 5 个学生 的所有班级。
以 任意顺序 返回结果表。
结果格式如下所示。
示例 1:
输入: Courses table: +---------+----------+ | student | class | +---------+----------+ | A | Math | | B | English | | C | Math | | D | Biology | | E | Math | | F | Computer | | G | Math | | H | Math | | I | Math | +---------+----------+ 输出: +---------+ | class | +---------+ | Math | +---------+ 解释: -数学课有 6 个学生,所以我们包括它。 -英语课有 1 名学生,所以我们不包括它。 -生物课有 1 名学生,所以我们不包括它。 -计算机课有 1 个学生,所以我们不包括它。
import pandas as pd
def find_classes(courses: pd.DataFrame) -> pd.DataFrame:
df = courses.groupby(['class'])['student'].count().reset_index()
cl = df[df['student'] >= 5]['class']
return pd.DataFrame(cl,columns = ['class'])
# 官方题解
import pandas as pd
def find_classes(courses: pd.DataFrame) -> pd.DataFrame:
df = courses.groupby('class').size().reset_index(name='count')
df = df[df['count'] >= 5]
return df[['class']]
较简单,官方题解更优雅
订单最多的客户
查找下了 最多订单 的客户的 customer_number
。
测试用例生成后, 恰好有一个客户 比任何其他客户下了更多的订单。
查询结果格式如下所示。
示例 1:
输入: Orders 表: +--------------+-----------------+ | order_number | customer_number | +--------------+-----------------+ | 1 | 1 | | 2 | 2 | | 3 | 3 | | 4 | 3 | +--------------+-----------------+ 输出: +-----------------+ | customer_number | +-----------------+ | 3 | +-----------------+ 解释: customer_number 为 '3' 的顾客有两个订单,比顾客 '1' 或者 '2' 都要多,因为他们只有一个订单。 所以结果是该顾客的 customer_number ,也就是 3 。
import pandas as pd
def largest_orders(orders: pd.DataFrame) -> pd.DataFrame:
orders = orders.groupby(['customer_number'])['order_number'].count().reset_index()
orders.sort_values(by = ['order_number'],ascending = False,inplace = True)
return orders.iloc[0:1,:1]
# 官方题解
import pandas as pd
def largest_orders(orders: pd.DataFrame) -> pd.DataFrame:
# 如果 orders 为空,返回一个空的 DataFrame。
if orders.empty:
return pd.DataFrame({'customer_number': []})
df = orders.groupby('customer_number').size().reset_index(name='count')
df.sort_values(by='count', ascending = False, inplace=True)
return df[['customer_number']][0:1]
有个很奇怪的现象:这是调用largest_orders前后的orders打印输出
order_number customer_number
0 1 1
1 2 2
2 3 3
3 4 3
customer_number order_number
2 3 2
0 1 1
1 2 1列居然很奇怪地被交换了,有可能时sort_values()导致的,总之还是像官方df[['customer_number']][0:1]这样输出安全点
按日期分组销售产品
要使用agg喽
编写解决方案找出每个日期、销售的不同产品的数量及其名称。
每个日期的销售产品名称应按词典序排列。
返回按 sell_date
排序的结果表。
结果表结果格式如下例所示。
示例 1:
输入:
Activities
表:
+------------+-------------+
| sell_date | product |
+------------+-------------+
| 2020-05-30 | Headphone |
| 2020-06-01 | Pencil |
| 2020-06-02 | Mask |
| 2020-05-30 | Basketball |
| 2020-06-01 | Bible |
| 2020-06-02 | Mask |
| 2020-05-30 | T-Shirt |
+------------+-------------+
输出:
+------------+----------+------------------------------+
| sell_date | num_sold | products |
+------------+----------+------------------------------+
| 2020-05-30 | 3 | Basketball,Headphone,T-shirt |
| 2020-06-01 | 2 | Bible,Pencil |
| 2020-06-02 | 1 | Mask |
+------------+----------+------------------------------+
解释:
对于2020-05-30,出售的物品是 (Headphone, Basketball, T-shirt),按词典序排列,并用逗号 ',' 分隔。
对于2020-06-01,出售的物品是 (Pencil, Bible),按词典序排列,并用逗号分隔。
对于2020-06-02,出售的物品是 (Mask),只需返回该物品名。
import pandas as pd
def categorize_products(activities: pd.DataFrame) -> pd.DataFrame:
groupby = activities.groupby(['sell_date'])
df = groupby.agg(
num_sold = ('product','nunique'),
products = ('product',lambda x:','.join(sorted(set(x))))
).reset_index()
return df
agg的使用方法为:
groupby.agg(
新列名 = ('原来要聚合的老列名':聚合方法)
)
每天的领导和合伙人
和上题一摸一样哦
对于每一个 date_id
和 make_name
,找出 不同 的 lead_id
以及 不同 的 partner_id
的数量。
按 任意顺序 返回结果表。
返回结果格式如下示例所示。
示例 1:
输入: DailySales 表: +-----------+-----------+---------+------------+ | date_id | make_name | lead_id | partner_id | +-----------+-----------+---------+------------+ | 2020-12-8 | toyota | 0 | 1 | | 2020-12-8 | toyota | 1 | 0 | | 2020-12-8 | toyota | 1 | 2 | | 2020-12-7 | toyota | 0 | 2 | | 2020-12-7 | toyota | 0 | 1 | | 2020-12-8 | honda | 1 | 2 | | 2020-12-8 | honda | 2 | 1 | | 2020-12-7 | honda | 0 | 1 | | 2020-12-7 | honda | 1 | 2 | | 2020-12-7 | honda | 2 | 1 | +-----------+-----------+---------+------------+ 输出: +-----------+-----------+--------------+-----------------+ | date_id | make_name | unique_leads | unique_partners | +-----------+-----------+--------------+-----------------+ | 2020-12-8 | toyota | 2 | 3 | | 2020-12-7 | toyota | 1 | 2 | | 2020-12-8 | honda | 2 | 2 | | 2020-12-7 | honda | 3 | 2 | +-----------+-----------+--------------+-----------------+ 解释: 在 2020-12-8,丰田(toyota)有领导者 = [0, 1] 和合伙人 = [0, 1, 2] ,同时本田(honda)有领导者 = [1, 2] 和合伙人 = [1, 2]。 在 2020-12-7,丰田(toyota)有领导者 = [0] 和合伙人 = [1, 2] ,同时本田(honda)有领导者 = [0, 1, 2] 和合伙人 = [1, 2]。
import pandas as pd
def daily_leads_and_partners(daily_sales: pd.DataFrame) -> pd.DataFrame:
groupby = daily_sales.groupby(['date_id','make_name'])
df = groupby.agg(
unique_leads = ('lead_id','nunique'),
unique_partners = ('partner_id','nunique')
).reset_index()
return df
合作过至少三次的演员和导演
易,没啥难度
编写解决方案找出合作过至少三次的演员和导演的 id 对 (actor_id, director_id)
示例 1:
输入: ActorDirector 表: +-------------+-------------+-------------+ | actor_id | director_id | timestamp | +-------------+-------------+-------------+ | 1 | 1 | 0 | | 1 | 1 | 1 | | 1 | 1 | 2 | | 1 | 2 | 3 | | 1 | 2 | 4 | | 2 | 1 | 5 | | 2 | 1 | 6 | +-------------+-------------+-------------+ 输出: +-------------+-------------+ | actor_id | director_id | +-------------+-------------+ | 1 | 1 | +-------------+-------------+ 解释: 唯一的 id 对是 (1, 1),他们恰好合作了 3 次。
import pandas as pd
def actors_and_directors(actor_director: pd.DataFrame) -> pd.DataFrame:
df = actor_director.groupby(['actor_id','director_id']).size().reset_index(name = 'times')
return df[df['times'] >= 3][['actor_id','director_id']]
使用唯一标识吗替换员工ID
就考察了一下数据合并,数据库风格的左连接
展示每位用户的 唯一标识码(unique ID );如果某位员工没有唯一标识码,使用 null 填充即可。
你可以以 任意 顺序返回结果表。
返回结果的格式如下例所示。
示例 1:
输入: Employees
表: +----+----------+ | id | name | +----+----------+ | 1 | Alice | | 7 | Bob | | 11 | Meir | | 90 | Winston | | 3 | Jonathan | +----+----------+EmployeeUNI
表: +----+-----------+ | id | unique_id | +----+-----------+ | 3 | 1 | | 11 | 2 | | 90 | 3 | +----+-----------+ 输出: +-----------+----------+ | unique_id | name | +-----------+----------+ | null | Alice | | null | Bob | | 2 | Meir | | 3 | Winston | | 1 | Jonathan | +-----------+----------+ 解释: Alice and Bob 没有唯一标识码, 因此我们使用 null 替代。 Meir 的唯一标识码是 2 。 Winston 的唯一标识码是 3 。 Jonathan 唯一标识码是 1 。
import pandas as pd
def replace_employee_id(employees: pd.DataFrame, employee_uni: pd.DataFrame) -> pd.DataFrame:
df = pd.merge(employee_uni,employees,how = 'right')
return df[['unique_id','name']]