![](/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.