目的:查询数据1和数据2中,red与red列相同 并且blue与blue列相同的,情况有多少。
(备注:两个数据中格式不一致,需要经过json提取等处理步骤)
思路步骤:
1、读取数据1,筛选需要的行,从expert_reco_num_stage_5 (json)提取red和blue数据,做为结果A
2、读取数据2,也提取red和blue数据,格式和上面一样(便于比较),作为结果B
3、A、B用指定列进行左连接,最终查询A和B中的red和blue是一样的数量有多少
import pandas as pd
import json
# 读取智能大师号码信息
path1 = r'./expert_recommend (1).csv'
df_data = pd.read_csv(path1)
# 筛选数据 : lottery_id是1001 并且recommend=1 的
data_ssq = df_data[(df_data['lottery_id']==1001) & (df_data['recommend']==1)].reset_index() # 重置索引
# 查看数据
print(data_ssq[['expert_id','issue_no','expert_reco_num_stage_5']].head())
data_ssq['expert_reco_num_stage_5'][0]
# 每次针对一种key进行提取,并 按升序排序后,重新形成字符串
# 参数:
# thecolume 对应的json列,
# color指要处理的key,即red或blue,不传默认取red
def getnum_ssq(thecolume, color):
# 字符串处理
one_data=eval(thecolume)
# 获取要处理的key
key1 = ''
if one_data.get(color): # 如果color有值,则取color
key1=color
else:
key1='red'
# print('key1:',key1)
# pd.json_normalize() 提取json中的指定key
# 提取并按照升序排序(axis=0按照数据大小排序;=1按照索引中数据大小排序)
expert_num_1 = pd.json_normalize(one_data.get(key1)).sort_values(by='$numberInt', axis=0, ascending=True)
expert_num_list1 = expert_num_1.values.tolist() # 转为list
# 列表保存值
list_t = []
for i in range(expert_num_1.shape[0]):
list_t.append(expert_num_list1[i][0]) # 因为结果只有1列
# print(list_t)
# 列表内容用逗号连接,转成字符串
expert_num1_res = ','.join(list_t)
return expert_num1_res
# 处理结果作为新的一列,结果A
# 注意此数据中如果真实数据是4,4,5,表中只会存 4,5,即red中不会出现相同的数字,blue一样
data_ssq['num5_red'] = data_ssq['expert_reco_num_stage_5'].apply(lambda x: getnum_ssq(x, 'red')) # reco_issue_no为文章预测的期次号
data_ssq['num5_blue'] = data_ssq['expert_reco_num_stage_5'].apply(lambda x: getnum_ssq(x, 'blue')) # reco_issue_no为文章预测的期次号
# data_ssq.head()
# 结果A
# 查看第一条expert_reco_num_stage_5的处理结果
print(data_ssq[['expert_id','issue_no','expert_reco_num_stage_5','num5_red','num5_blue']].iloc[0])
path3 = r'./号码.csv'
kj_data_ssq = pd.read_csv(path3)
kj_data_ssq[['s_issue_no','s_result_area_1','s_result_area_2']].head()
# red对应在area_1,blue在area_2
# 查看数据
print(kj_data_ssq['s_result_area_1'][0])
print(kj_data_ssq['s_result_area_2'][0])
# 功能:把字符串转为数组后,重新排序,形成新的字符串
# 参数:
# str1 字符串,是字符串类型的数值 03,19,02
# sep1 原来的分割符
# sep2 新字符串的分隔符
def str_sort_2(str1, sep1, sep2):
# 去除无用的0,利用int类型
a = str1.split(sep1)
b = [int(x) for x in a]
list1 = [str(x) for x in b]
# 注意:结果A中,如果是4,4,5,表中只会存 4,5。为了和 结果B便于比较,结果B也要做类似处理
list2 = list(set(list1)) # 利用集合去重
list2.sort() # 升序排序,可以改变源数据,降序时设置 reverse=True
str2 = sep2.join(list2)
return str2
print('函数测试:',str_sort_2('03,2,6,3,8', ',', ','))
# 号码排序,统一为str类型
# red、blue提取(s_result_area_2只有一个,只要也转换成字符串即可)
kj_data_ssq['win_number_red_res'] = kj_data_ssq['s_result_area_1'].apply(lambda x : str_sort_2(x, ',', ','))
kj_data_ssq['win_number_blue_res'] = kj_data_ssq['s_result_area_2'].astype(str)
# s_issue_no重命名为issue_no,便于和 后续连接时使用.永久修改
kj_data_ssq.rename(columns={'s_issue_no': 'issue_no'}, inplace=True) # rename可以在修改部分列时使用
# 查看结果B
kj_data_ssq[['s_result_area_1','s_result_area_2','win_number_red_res','win_number_blue_res','issue_no']].head()
merge_ssq = pd.merge(data_ssq, kj_data_ssq, how='left', on='issue_no')
# 筛选出 两者相同/不同 的 df[df['某一列'] != df['某一列']]
# merge_ssq[merge_ssq['num5_new'] == merge_ssq['win_number_res']]
# merge_ssq
# 查找哪个expert_id的"红球一样,蓝球也一样"这种数据最多
find_ssq = merge_ssq.loc[ (merge_ssq['num5_red'] == merge_ssq['win_number_red_res']) & (merge_ssq['num5_blue'] == merge_ssq['win_number_blue_res']),
['expert_id', 'issue_no', 'lottery_id', 'num5_red', 'num5_blue', 'win_number_red_res', 'win_number_blue_res']]
res3 = find_ssq.groupby(by='expert_id').count()
res3.sort_values(by='lottery_id', ascending=False)