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_type
和 department
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
我即将开始一些 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_type
和 department
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