簡體   English   中英

來自 SQL 查詢的 Python 數據分析

[英]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_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 項目

如果您願意考慮其他軟件包,請查看構建在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM