标签: Python

  • Amazon Sagemaker 常用方法

    Amazon Sagemaker 常用方法

    从 S3 下载文件:

    import boto3
    s3 = boto3.resource('s3')
    
    s3.meta.client.download_file('bucket', 'origin_object_key', 'local_path')

    往 S3 上传文件:

    s3.meta.client.upload_file('local_path', 'bucket', 'origin_object_key')

    python zip 解压

    import zipfile
    with zipfile.ZipFile(path_to_zip_file, 'r') as zip_ref:
        zip_ref.extractall(directory_to_extract_to)
  • Pandas DataFrame 常用操作

    Pandas DataFrame 常用操作

    Pandas 读取 Excel 或者 csv 文件:

    import pandas as pd
    
    pd.read_excel(r'filepath', sheet_name='sheet1')
    pd.read_csv(r'filepath')

    DataFrame 拼接:

    df1.append(df2)

    DataFrame 筛选:

    df.loc[df['A'] == 1],多条件 df.loc[(df['A'] == 1) & (df['B'] == 2)]

    DataFrame 分组:

    df.groupby(by=['A','B','C'])

    DataFrame 删除列:

    df.drop(labels=['A', 'B'], axis=1)

    DataFrame 去重:

    df.drop_duplicates(subset=['A','B','C','D'])

    从 DataFrame 的头部或者尾部截取数据输出:

    df.head()
    df.tail(3)

    不要在 for 循环中 append 数据,效率非常低

    Pandas 的数据不能直接修改,添加属性需要复制一份:

    import copy
    
    new_frame_data = copy.copy(old_frame_data)
    new_frame_data.attr = value
  • 为 AWS Python Lambda 函数添加层,支持使用 pandas 库

    为 AWS Python Lambda 函数添加层,支持使用 pandas 库

    参考:

    1. 创建和共享 Lambda 层
    2. How to use pandas in AWS Lambda

    步骤1~4需要在 AWS 的 EC2 实例上进行,以便使用相同的依赖环境,这里使用 AWS 的 Sagemaker 进行。

    步骤1:

    找到需要添加层的 Lambda 函数的 Python 版本,在 AWS EC2 环境创建层时需要使用相同的版本,创建 AWS Lambda 函数时能看到,可选用的 Python Lambda 函数版本为 3.9,EC2 环境使用 Python 3.9.13 版本。

    conda create -n aws_lambda_env python==3.9.13conda activate aws_lambda_env

    在 Sagemaker 环境下,激活 conda 虚拟环境需要使用:

    source activate aws_lambda_env

    步骤2:

    创建一个文件夹

    mkdir python

    步骤3:

    安装需要添加的库到这个环境中

    pip install openpyxl pandas -t python

    步骤4:

    打包目录

    zip -r pandas.zip python

    步骤5:

    在 AWS 控制台创建层,然后上传打包好的层 pandas.zip

    在 AWS 控制台上传打包好的层

    步骤6:

    创建一个新的 Lambda 函数,选择可以添加层的运行时环境,这里选择的是 Python 3.9

    创建 Lambda 函数

    步骤7:

    为创建的 Lambda 函数添加层:

    添加一个 Layer

    选择刚刚创建的层

    选择刚刚创建的层

    最后写一段代码测试一下,是否能 import 成功新添加层的库。

    import logging
    
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    
    def lambda_handler(event, context):
         logger.info(pd.__version__)
  • “无重复字符的最长子串(Longest Substring Without Repeating Characters)”问题的 Python3 解答

    “无重复字符的最长子串(Longest Substring Without Repeating Characters)”问题的 Python3 解答

    题目描述

    给定一个字符串,找出不含有重复字符的最长子串的长度。

    示例

    示例 1:

    输入: "abcabcbb"
    输出: 3 
    解释: 无重复字符的最长子串是 "abc",其长度为 3。
    

    示例2:

    输入: "bbbbb"
    输出: 1
    解释: 无重复字符的最长子串是 "b",其长度为 1。
    

    示例3:

    输入: "pwwkew"
    输出: 3
    解释: 无重复字符的最长子串是 "wke",其长度为 3。
         请注意,答案必须是一个子串,"pwke" 是一个子序列 而不是子串。
    

    测试用例

    abcabcbb    3
    bbbbb   1
    pwwkew  3
    ""      0
    au      2
    dvdf    3
    cdd     2
    ddc     2
    

    解题思路

    逐字符遍历字符串,记录第一个无重复子串s[0]。查看下一个字符是否被rStr所包含,不包含就将此字符加到rStr的末尾,直到找到一个已经包含在rStr中的字符,此时,这个无重复子串的长度就有了。依次方法,继续查找子串,并与当前已经找到的子串做比较,记录最长的子串长度即可。字符串遍历完毕,问题得解。

    解答

    class Solution:
        def lengthOfLongestSubstring(self, s):
            """
            :type s: str
            :rtype: int
            """
            sLen = len(s)
            if sLen < 1:
                return 0
            rLen = 1
            startIndex = 1
            endIndex = 0
            rStr = s[0]
    
            while startIndex != sLen != endIndex:
                for i in range(startIndex, sLen):
                    if s[i] not in rStr:
                        endIndex = i + 1
                        rStr = s[startIndex - 1:endIndex]
                    else:
                        break
                rLen = max(rLen, len(rStr))
                if startIndex != sLen:
                    rStr = s[startIndex]
                startIndex = startIndex + 1
            return rLen
    
    

    算法分析

    上述算法用Python3实现的时候有一个边界问题,字符串为空的情况下长度为 0,返回此值即可,否则下面初始化第一个无重复子串就溢出了。

    上述算法时间复杂度是O(n^2),并不理想。

    中文官网的题目地址:无重复字符的最长子串

  • “两数之和(Two Sum)”问题的 Python3 解答

    “两数之和(Two Sum)”问题的 Python3 解答

    题目描述

    给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

    示例

    给定 nums = [2, 7, 11, 15], target = 9
    因为 nums[0] + nums[1] = 2 + 7 = 9
    所以返回 [0, 1]

    解题思路

    要求的结果是两个索引组成的 List:[aIndex, bIndex],这两个索引对应的值记为 a, b。

    遍历列表,假设列表中第1项的值 a 是结果 List 中的一个索引的值,那么用 target 减去 a 后得到的结果 b 就是就是要找的另一个索引的值,列表除掉 a 后的子列表里面,如果 b 存在,问题已解——答案是 a 的索引和 b 的索引组成的列表 [aIndex, bIndex]。

    如果不存在,将列表的第二项赋值给 a,继续寻找 b,直到找到为止。

    解答

    class Solution:
        def twoSum(self, nums, target):
            """
            :type nums: List[int]
            :type target: int
            :rtype: List[int]
            """
    
            i = 0
    
            for num in nums:
                nextNum = target - num
                j = i + 1
                if nextNum in nums[j:]:
                    return [i, nums[j:].index(nextNum) + i + 1]
                i += 1
    
    

    中文官网的题目地址:两数之和

  • “两数相加(Add Two Numbers)”问题的 Python3 解答

    “两数相加(Add Two Numbers)”问题的 Python3 解答

    题目描述

    给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。

    你可以假设除了数字 0 之外,这两个数字都不会以零开头

    示例

    输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
    输出:7 -> 0 -> 8
    原因:342 + 465 = 807

    测试用例

    [2,4,3]
    [5,6,4]
    
    [1]
    [9,9]
    
    [5]
    [5]
    
    [0]
    [7,3]
    
    [9,9]
    [9]
    

    解题思路

    遍历链表,按节点两两相加,有进位将进位加到下一个节点。

    解题思路很简单,此题被标记为中等难度,是因为:

    1. 数据结构是链表;
    2. 两个链表长度不一定相等,尤其是有进位情况下的处理需考虑。

    解答

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution:
        def addTwoNumbers(self, l1, l2):
            """
            :type l1: ListNode
            :type l2: ListNode
            :rtype: ListNode
            """
            l3 = l1
    
            while l1 != None or l2 != None:
                sum = l1.val + l2.val
                l1.val = sum % 10
    
                if sum >= 10:
                    if l1.next != None:
                        l1.next.val = l1.next.val + 1
    
                        if l1.next.val >= 10 and l2.next == None:
                            l2.next = ListNode(0)
                    else:
                        l1.next = ListNode(1)
    
                else:
                    if l1.next == None and l2.next != None:
                        l1.next = ListNode(0)
    
                if l2.next == None:
                    break
    
                l1 = l1.next
                l2 = l2.next
    
            return l3
    

    算法分析

    上述算法通过一次遍历完成,没有用单独的变量存储 carry 值。两个链表同节点相加的结果最大为 9 + 9 + 1 = 19,所以结果链表中对应节点的值永远可以用(l1[index] + l2[index] + carry) % 10来得到。

    上述算法将进位 carry 计入到了下一位中。具体解题过程为

    1. 用新变量 l3 保留对 l1 的引用
    2. l1 和 l2 对应节点做加法
    3. 有进位且 l1 有下一节点的情况下,将进位加入到 l1 的下一个节点;l1 没有下一个节点就给 l1 添加一个值为 1 的节点;没有进位执行步骤4
    4. l1 没有下一个节点了,但是 l2 还有下一个节点,就给 l1 添加一个值为 0 的节点
    5. 3 或 4 步骤执行完毕,如果 l2 没值了,就跳出循环,返回 l3,原题得解;否则将 l1 和 l2 移动一个节点,执行步骤2

    中文官网的题目地址:两数相加