You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas带筛选的列操作:字符串字符转换问题求助

解决Pandas DataFrame中卡片字符转换问题

问题描述

现有如下Pandas DataFrame:

ID               Cards  ...       opp cards1
0       flop850262436159b10  ('3h', 'tc', '5s')  ...  0.000000     10
1       flop850262436159b10  ('3h', 'tc', '5s')  ...  0.533690     10
2       flop850262436159b10  ('3h', 'tc', '5s')  ...  0.021292     10
3       flop850262436159b10  ('3h', 'tc', '5s')  ...  0.022805     10
4       flop850262436159b10  ('3h', 'tc', '5s')  ...  0.999691     10
                    ...                 ...  ...       ...    ...
749995  flop573952955203b10  ('ts', '2c', 'jd')  ...  0.162980     10
749996  flop573952955203b10  ('ts', '2c', 'jd')  ...  0.541003     10
749997  flop573952955203b10  ('ts', '2c', 'jd')  ...  0.341836     10
749998  flop573952955203b10  ('ts', '2c', 'jd')  ...  0.219956     10
749999  flop573952955203b10  ('ts', '2c', 'jd')  ...  0.363605     10

需求:提取Cards列中每个卡片的第一个字符(比如('3h', 'tc', '5s')里的3、t、5),若该字符为字母(如t、j),则转换为对应整数(例如t转为10),否则保持原数字字符。

原尝试代码(无效):

df = pd.read_csv('path', sep=";")

if (df['cards'].astype(str).str[0] =="t").any() == True:
    df['cards1'] = 10
else:
    df['cards1'] = df['cards'].astype(str).str[0]

问题根源:any()会判断整个列是否存在符合条件的行,只要有一行满足,就会把整个cards1列设为10,无法实现逐行判断。

解决方案

方法1:解析元组+自定义函数处理

先将Cards列的字符串形式元组转为实际元组,再逐个处理每个卡片的第一个字符:

import pandas as pd

# 读取数据
df = pd.read_csv('path', sep=";")

# 定义字符映射字典,可根据需求扩展(如j=11、q=12等)
char_map = {'t': 10, 'j': 11, 'q': 12, 'k':13, 'a':1}

def process_cards(cards_str):
    # 转换字符串元组为实际元组
    cards = eval(cards_str)
    processed = []
    for card in cards:
        first_char = card[0].lower()
        # 匹配映射表则替换为数字,否则保留原字符
        processed.append(char_map.get(first_char, card[0]))
    return processed

# 生成处理后的列,若仅需第一个卡片的结果,可改为process_cards(x)[0]
df['cards1'] = df['Cards'].apply(process_cards)

方法2:正则表达式提取+映射

无需解析元组,直接用正则匹配所有卡片的第一个字符再替换:

import pandas as pd
import re

df = pd.read_csv('path', sep=";")

char_map = {'t': '10', 'j': '11', 'q': '12', 'k':'13', 'a':'1'}

def get_processed_chars(cards_str):
    # 提取所有卡片的第一个字符
    chars = re.findall(r"'(\w)", cards_str)
    # 替换字母为对应数字
    return [char_map.get(c.lower(), c) for c in chars]

df['cards1'] = df['Cards'].apply(get_processed_chars)

方法3:针对单卡片的简化处理

若仅需提取Cards列中第一个卡片的第一个字符并转换:

import pandas as pd
import numpy as np

df = pd.read_csv('path', sep=";")

# 提取第一个卡片的第一个字符
first_chars = df['Cards'].str.extract(r"'(\w)").squeeze()

# 逐行判断替换
df['cards1'] = np.where(first_chars.str.lower() == 't', 10,
                        np.where(first_chars.str.lower() == 'j', 11,
                                 first_chars))

注意事项

  • 若数据来源不可信,建议避免使用eval(),优先选择正则表达式解析;
  • 映射字典可根据实际需求扩展更多扑克牌面的转换规则;
  • 所有方法均实现了逐行判断处理,解决了原代码整列赋值的问题。

内容的提问来源于stack exchange,提问作者Raphaël Ambit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 17:31:00