Python 来自 SQL 查询的数据分析

Python Data Analysis from SQL Query

我即将开始一些 Python 数据分析,这与我以前做过的任何事情都不一样。我目前正在研究 numpy,但到目前为止,它并没有让我深入了解如何做到这一点。

我正在使用 python 2.7.14 Anaconda 和 cx_Oracle 来查询复杂记录。

每条记录都将是一个唯一的个体,其中有一列用于员工 ID、关系元组(关系类型代码与部门编号配对,可能包含多个)、帐户标志(标志字符串,可能包含多个)。 (共 3 列)

所以一条记录可能是:

 [(123456), (135:2345678, 212:4354670, 198:9876545), (Flag1, Flag2, Flag3)]

我需要开发一个 python 脚本来获取这些记录并创建各种计数。

示例记录将被计入至少 9 个不同的计数
有多少关系:135
有多少关系:212
有多少关系:198
部门人数:2345678
部门人数:4354670
部门人数:9876545
有多少个标志:Flag1
有多少个标志:Flag2
有多少标志:Flag3

另一个棘手的部分是,我无法预先定义关系代码、部门或标志,我计算的内容必须由从查询中检索到的数据来确定。

一旦我理解了如何做到这一点,希望下一步也能直观地了解 X 与 Flag y 之间的关系等。

我知道这有很多问题要问,但如果有人能给我指出正确的方向,这样我就可以研究或尝试一些非常有帮助的教程。谢谢!

如果您愿意考虑其他软件包,请查看构建在 numpy 之上的 pandas。您可以将 sql 语句直接读入数据框,然后进行过滤。

例如,

import pandas
sql = '''SELECT * FROM <table> WHERE <condition>'''
df = pandas.read_sql(sql, <connection>)

# Your output might look like the following:

        0                                         1                     2
0   12346   (135:2345678, 212:4354670, 198:9876545) (Flag1, Flag2, Flag3)
1   12345   (136:2343678, 212:4354670, 198:9876545) (Flag1, Flag2, Flag4)

# Format your records into rows
# This part will take some work, and really depends on how your data is formatted
# Do you have repeated values? Are the records always the same size?

# Select only the rows where relationship = 125
rel_125 = df[df['Relationship'] = 125]

pandas 格式比问答更深入,但这里有一些很好的资源:10 Minutes to Pandas

您也可以直接过滤行,尽管这可能不是最有效的。例如,以下查询仅选择关系以“212”开头的行。

df[df['Relationship'].apply(lambda x: any(y.startswith('212') for y in x))]

至少你需要结构化这些数据才能进行良好的分析,你可以在你的数据库引擎或python中完成(我将通过这样,像 SNygard 建议的那样使用 pandas。

起初,我创建了一些假数据(由您提供):

import pandas as pd 
import numpy as np
from ast import literal_eval

data = [[12346, '(135:2345678, 212:4354670, 198:9876545)', '(Flag1, Flag2, Flag3)'],
[12345, '(136:2343678, 212:4354670, 198:9876541, 199:9876535)', '(Flag1, Flag4)']]

df = pd.DataFrame(data,columns=['id','relationships','flags'])
df = df.set_index('id')
df

这个 return 像这样的数据框: raw_pandas_dataframe

为了按列汇总或计数,我们需要改进我们的数据结构,以某种方式我们可以应用部门、关系或标志的分组操作。

我们会将关系和标志列从字符串类型转换为 python 字符串列表。因此,标志列将是一个 python 标志列表,而关系列将是一个 python 关系列表。

df['relationships'] = df['relationships'].str.replace('\(','').str.replace('\)','')
df['relationships'] = df['relationships'].str.split(',')

df['flags'] = df['flags'].str.replace('\(','').str.replace('\)','')
df['flags'] = df['flags'].str.split(',')
df

结果是: dataframe_1

relationships 列转换为列表后,我们可以创建一个包含尽可能多列的新数据框 作为该列表中的关系,我们有。

rel = pd.DataFrame(df['relationships'].values.tolist(), index=rel.index)

之后我们需要堆叠保留其索引的列,因此我们将使用 pandas multi_index:id 和关系列号 (0,1,2,3)

relations = rel.stack()
relations.index.names = ['id','relation_number']
relations

我们得到:dataframe_2

此时我们所有的关系都排成一行,但我们仍然不能使用 relation_type 特征。因此,我们将使用 :.

将关系数据拆分为两列:relation_typedepartment
clear_relations = relations.str.split(':')
clear_relations = pd.DataFrame(clear_relations.values.tolist(), index=clear_relations.index,columns=['relation_type','department'])
clear_relations

结果是 dataframe_3_clear_relations

我们的关系已经可以分析了,但是我们的flags结构还是很没用。因此,我们会将标志列表转换为列,然后将它们堆叠起来。

flags = pd.DataFrame(df['flags'].values.tolist(), index=rel.index)
flags = flags.stack()
flags.index.names = ['id','flag_number']

结果是dataframe_4_clear_flags


瞧!一切就绪,可以分析了!

因此,例如,我们有多少种关系,其中一种是最大的:

clear_relations.groupby('relation_type').agg('count')['department'].sort_values(ascending=False)

我们得到:group_by_relation_type


所有代码:Github project