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')
查找拥有有效邮箱的用户

编写一个解决方案,以查找具有有效电子邮件的用户。

一个有效的电子邮件具有前缀名称和域,其中:

  1.  前缀 名称是一个字符串,可以包含字母(大写或小写),数字,下划线 '_' ,点 '.' 和/或破折号 '-' 。前缀名称 必须 以字母开头。
  2.  为 '@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')
  1. 基本语法

    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)
  2. 参数

    • 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_idevent_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']]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值