![](/img/trans.png)
[英]Use Python to Query SQL Server Analysis Services (SSAS) cube Data
[英]Python Data Analysis from SQL Query
我即将开始一些 Python 数据分析,这与我以前做过的任何事情都不一样。 我目前正在学习 numpy,但到目前为止它并没有让我了解如何做到这一点。
我正在使用带有 cx_Oracle 的 python 2.7.14 Anaconda 来查询复杂记录。
每条记录都将是一个唯一的个体,其中有一列用于员工 ID、关系元组(关系类型代码与部门编号配对,可能包含多个)、帐户标志(标志字符串,可能包含多个)。 (共 3 列)
所以一个记录可能是:
[(123456), (135:2345678, 212:4354670, 198:9876545), (Flag1, Flag2, Flag3)]
我需要开发一个 python 脚本来获取这些记录并创建各种计数。
示例记录将被计入至少 9 个不同的计数
有多少关系:135
有多少关系:212
有多少关系:198
部门人数:2345678
部门人数:4354670
部门人数:9876545
带 Flag 数量:Flag1
带 Flag 的数量:Flag2
带 Flag 的数量:Flag3
另一个棘手的部分是,我无法预先定义关系代码、部门或标志 我要计算的内容必须由从查询中检索到的数据来确定。
一旦我理解了如何做到这一点,希望下一步也能得到 X 有多少关系 Flag y 等等,这将是直观的。
我知道这有很多问题要问,但是如果有人能指出我正确的方向,这样我就可以研究或尝试一些非常有帮助的教程。 谢谢!
至少您需要对这些数据进行结构化以进行良好的分析,您可以在数据库引擎或 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
这将返回一个像这样的数据帧: raw_pandas_dataframe
为了按列汇总或统计,我们需要改进我们的数据结构,以某种方式我们可以应用group by 操作与部门、关系或标志。
我们将把我们的关系和标志列从字符串类型转换为字符串的 Python 列表。 因此,flags 列将是一个 Python 标志列表,而 Relations 列将是一个 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']
瞧!,一切就绪,可以分析了!。
因此,例如,我们拥有每种类型的关系有多少,其中一个是最大的:
clear_relations.groupby('relation_type').agg('count')['department'].sort_values(ascending=False)
我们得到: group_by_relation_type
所有代码: Github 项目
如果您愿意考虑其他软件包,请查看构建在 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 分钟到 Pandas 。
您也可以直接过滤行,尽管它可能不是最有效的。 例如,以下查询仅选择关系以“212”开头的行。
df[df['Relationship'].apply(lambda x: any(y.startswith('212') for y in x))]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.