2013-08-27 17 views
0

我正在編寫一個代碼來對數據進行分類,並獲得平均值和標準偏差。這裏是我的數據的例子。對數據進行分類,計算每個類別的平均值和標準差

3917 1 -0.662261 25.148 22.9354 68.8076 
3918 1 12.7649 18.7451 7.68473 69.0063 
3919 1 -9.56836 -23.3265 -61.953 68.8357 
3920 1 11.6292 31.6525 -29.3697 69.1372 
3921 2 26.4837 -66.7897 12.0257 69.2282 
3922 1 -9.81652 14.3788 9.38343 69.1217 
3923 2 39.931 -88.1879 109.498 69.1604 
3924 1 4.5502 3.53887 -6.59604 69.486 
3925 2 13.6801 -24.6628 -5.7568 69.9398 
3926 1 -10.5635 7.05517 -8.82785 70.2263 

正如你所看到的,有6列。我正在考慮三步計算。

  1. 根據第6列對這些數字進行分類。第6列由0〜n的浮點數組成。我希望生成n個部分(或子矩陣,或其他),如0〜1,1〜2,2〜3 .... n-1〜n。最後一個數字應該是最後一個數據的數字,因爲我希望能夠創建部分。例如,如果最後一個數字是121.2513,最後一部分應該是120〜121以包含該數據。

  2. 將列1〜5的所有其他數字重新分配給基於第6列的相應子部分。如果在特定部分中沒有編號,則將其打印爲0.將會有n個小節。每個小節中的元素數量將是隨機的。

  3. 得到每個子段的第3,第4和第5列的平均值和標準偏差,並將輸入文件寫入輸入文件中,第'小節中的元素數,小節的開始數以及第3小節的平均值和標準差,第4列和第5列'

我正在嘗試使用多個for循環,但它變得太複雜,並且會出錯。有沒有其他簡單的方法來分類數據,與每個子部分一起玩,並用Python打印出來?另外,我的for循環根本不起作用。任何簡單的示例建議使用這些數據?

+2

請編輯您的文章以包括您的* for循環根本不工作* ...部分 –

+1

您是否在使用[numpy](http://www.numpy.org)?如果不是,你有沒有理由不能?它使得這種代碼變得簡單很多(與scipy和/或pandas一起),並避免了所有顯式循環,使得你無法正確使用。 – abarnert

+0

你可以發佈你迄今爲止寫的代碼嗎? – scohe001

回答

2

這個任務適合熊貓圖書館。 (http://pandas.pydata.org/)根據我對你的帖子的理解,你想要計算列方法和標準偏差。要計算行方向統計量,請將參數axis=1添加到平均值和std函數中。 在下面的代碼,示例性已被保存到「tmp.txt」的第一個步驟將其加載;然後它是簡單在數據幀,以計算統計

import pandas as pd 
df =pd.read_csv('tmp.txt',sep=' ',header=None) 
means = df.mean() 
stds = df.std() 

有關大熊貓的更多信息,取看快速介紹:http://pandas.pydata.org/pandas-docs/stable/10min.html

+0

我可以詢問'分類'部分嗎?如何使用numpy或pandas對基於第6列值的所有數據進行分類? – exsonic01

+0

我不確定你的意思,但你可以執行各種選擇和分組操作。例如,假設您只想計算第6列(列名稱5)> = 69中具有值的行的標準偏差。這只是:'df [df [5]> = 69] .std()'對於列中的分類值,也可以使用'groupby()'運算符。看看'10分鐘到熊貓'的鏈接 - 它提供了更多細節。 – user1470788

0

我假設你有一個列表列表中的矩陣,並告訴你如何開始(但是,正如我在評論中提到的,如果你有你的矩陣在一個numpy arraymatrix,這一切都會更容易 - 也更快。)


如果你只是有一個值作爲一個大的多行字符串,你可以將其轉換成類似這樣的浮點值列表的列表:

m = [[float(col) for col in line.split()] for line in s.splitlines()] 

現在,通過「分類基於這些數字在第6列「,這聽起來是你想要的是按照該列的整數值對它們進行分組。

Python自帶一個groupby函數,它可以完成您想要的大部分功能,但您必須先對數據進行排序。

在Python中,排序和分組以及相關函數總是讓您傳遞一個關鍵函數。您不必對第6列進行排序和分組,您可以使用第6列作爲關鍵字對整行進行排序和分組。

但實際上,你不想使用第6列的值作爲關鍵字,你想使用整數值的第6列。對於前者,你會使用自帶的STDLIB的itemgetter功能,但這樣做更復雜的東西,你最好寫它的函數:

def keyfunc(row): 
    return int(row[5]) 
groups = groupby(sorted(data, key=keyfunc), key=keyfunc) 

(如果你反覆這樣做,你可能希望編寫一個包裝函數,用相同的密鑰對組進行排序,所以你不必重複自己,並且弄錯了它。)

這是什麼給你的是一個帶有迭代器的迭代器,它有點難打印出來:

[(k, list(g)) for k, g in groups] 

但你得到的是:

[(68, 
    [[3917.0, 1.0, -0.662261, 25.148, 22.9354, 68.8076], 
    [3919.0, 1.0, -9.56836, -23.3265, -61.953, 68.8357]]), 
(69, 
    [[3918.0, 1.0, 12.7649, 18.7451, 7.68473, 69.0063], 
    [3920.0, 1.0, 11.6292, 31.6525, -29.3697, 69.1372], 
    [3921.0, 2.0, 26.4837, -66.7897, 12.0257, 69.2282], 
    [3922.0, 1.0, -9.81652, 14.3788, 9.38343, 69.1217], 
    [3923.0, 2.0, 39.931, -88.1879, 109.498, 69.1604], 
    [3924.0, 1.0, 4.5502, 3.53887, -6.59604, 69.486], 
    [3925.0, 2.0, 13.6801, -24.6628, -5.7568, 69.9398]]), 
(70, [[3926.0, 1.0, -10.5635, 7.05517, -8.82785, 70.2263]])] 

所以,每個k是整數的類別進行分組,並且每個g是所有該類別中的行(排序順序)。

(需要注意的是,因爲groups是一個迭代器,如果你print此,groups現在是空的。)

這需要你的第一個問題的關心,我想大多數你的第二個的(我不確定你到底想要什麼)。

對於第三個,你首先需要遍歷組:

for k, g in groups: 

如果你多次去遍歷組,要立即它的列表,然後遍歷該清單。

對於每個組,您想對一些列進行統計。最簡單的方法就是使用一個模塊來處理所有的數學問題。 PyPI上的stats模塊是一個不錯的選擇,特別是現在(稍有變化),它可能最終會在即將到來的Python版本的標準庫中出現。

但我只是顯示平均值,因爲這是微不足道的。

所以:

def mean(sequence): 
    return sum(sequence)/len(sequence) 

for k, g in groups: 
    rows = list(g) 
    print(k) 
    for column_index in 2, 3, 4: 
     column = [row[column_index] for row in rows] 
     print(mean(column)) 

很可能有很多,這個代碼不這樣做,你所需要的,但我希望它足以讓你開始,當你遇到問題要問更具體的問題。

0

正如其他人所說,你可能想看看numpy或pandas,特別是如果你的數據集很大。但是,在純Python中以及正確的數據結構也很容易實現。在這種情況下,我只需使用defaultdict作爲部分,關鍵是將第六列向下舍入,映射到列表元組(或更復雜的數據結構),然後您可以在其中收集列值:

from collections import defaultdict 
sections = defaultdict(lambda: ([], [], [], [], [])) 

with open("mydata.txt") as f: 
    #parse all non-empty lines into a list of lists of floats 
    lines = [x.strip() for x in f.read().split("\n")] 
    data = [map(float, x.split(" ")) for x in lines if x] 

for row in data: 
    #get the corresponding section (and create it if it doesn't exist) 
    section = sections[int(row[5])] 
    for x in range(5): 
     #append the column values to the respective lists 
     section[x].append(row[x]) 

現在sections包含易於使用的格式的數據;簡單地遍歷它,並計算您感興趣的各行的平均值和標準偏差:

for s, columns in sections.items(): 
    #assuming "mean" is a function that calculates the average of a list 
    print "mean of section [%i,%i) column 3 is %f" % (s, s+1, mean(columns[2])) 

此擴展到多個/不同的列和函數應該是微不足道的。

+0

謝謝,但我需要在150多個小節中對數據進行分類。明確地寫所有範圍的類別將是太長,而不是'pythonic'的方式... – exsonic01

+0

@ user1798797「明確地寫所有範圍的類別」 - 不知道你在說什麼,我不知道你理解解。像打印每個部分的列的平均值可以用大約三行代碼來完成,所以我不認爲它「太長」...給我一點時間,我會爲此寫一些示例代碼。 – l4mpi

相關問題