2014-01-07 18 views
2

我有一組CSV數據,它們是4203x37,我重塑爲50436x4以便找到每次記錄的12組3D點之間的歐幾里得距離-步。這不適用於我的實際數據,但奇怪的是,當我用隨機數重新創建數據時,代碼如下所示...當函數應用於行時,pandas'.groupby函數的奇怪問題

這是我的實際數據的代碼,它不起作用。

df_f_2_norm = df_f.loc[:,'Time':'label37'] # Select columns 
N = 12 # Nr of points 

# Drop label1 column for later use 
df_f_2_norm_time = df_f_2_norm['Time'] 
df_f_2_norm = df_f_2_norm.drop('Time',1) 

# Get shape of data frame 
shp = df_f_2_norm.shape 

# Use numpy.reshape to reshape the underlying data in the DataFrame 
df_f_2_norm = pd.DataFrame(df_f_2_norm.values.reshape(-1,3),columns=list('XYZ')) 
df_f_2_norm["Time"] = np.repeat(np.array(df_f_2_norm_time), N) # Number of points per time-label: 12 

# Find the Euclidean distance (2-norm) 
N_lim = int(0.5*N*(N-1)) 
result_index = ['D{}'.format(tag) for tag in range(1,N_lim+1)] # Column labels 
two_norm = df_f_2_norm.groupby('Time')[["X", "Y", "Z"]].apply(lambda g: pd.Series(pdist(g), index=result_index)) 

現在,如果我們看一下two_norm的形狀,它應具有的4203x66即66米歐幾里得距離的形狀爲12分,每時間戳其中有4203,每行一個。

事實上答案是:AssertionError: Index length did not match values - 所以它不喜歡我給它的列標籤。好吧,如果我們去掉標籤,只是做的,而不是

two_norm = df_f_2_norm.groupby('Time')[["X", "Y", "Z"]].apply(lambda g: pd.Series(pdist(g)) 

然後我們得到的(8307846,)形狀(print two_norm.shape) - 我不太明白這裏發生,但現在看來,它甚至不是堆疊的所有結果在彼此之上。

它變得更好,但因爲下面的代碼不工作,直到1140列,因此,如果我們讓

df_f_2_norm = df_f_2_norm[:1140] 

然後我們得到如下形狀:(95,66)

這是正確的,直到這一點,但如果我們做

df_f_2_norm = df_f_2_norm[:1152] 

相反,它提供了:(6480,)

因此,有些東西顯然已經變成了梨形,但如果我們真的看看這一點的數據,沒有什麼看起來很奇怪。

   X   Y  Z Time 
1127 -614.770 207.624 120.859 2.533 
1128 791.318 291.591 64.160 2.550 
1129 728.892 283.473 -207.306 2.550 
1130 939.871 251.387 -145.103 2.550 
1131 702.987 287.165 398.151 2.550 
1132 480.309 285.745 590.925 2.550 
1133 723.493 248.699 607.543 2.550 
1134 255.664 183.618 -108.176 2.550 
1135 -90.333 196.879 -261.102 2.550 
1136 -442.132 236.314 -419.216 2.550 
1137 133.428 216.805 242.896 2.550 
1138 -242.201 192.100 191.588 2.550 
1139 -616.844 210.060 123.202 2.550 
1140 -655.054 1390.084 -359.369 1.100 
1141 -726.517 1222.015 -590.799 1.100 
1142 -671.655 1146.959 -797.080 1.100 
1143 -762.048 1379.722 8.505 1.100 
1144 -981.748 1169.959 72.773 1.100 
1145 -1011.853 968.364 229.070 1.100 
1146 -778.290 827.571 -370.463 1.100 
1147 -761.608 460.835 -329.487 1.100 
1148 -815.330 77.501 -314.721 1.100 
1149 -925.764 831.944 -34.206 1.100 
1150 -1009.297 475.362 -73.077 1.100 
1151 -1193.310 139.839 -142.666 1.100 
1152 -631.630 1388.573 -353.642 1.117 
1153 -697.771 1234.274 -593.501 1.117 

所以這只是奇怪的。於是,我就用複製隨機數的問題,但它的所有作品完美,連標籤,這只是沒有任何意義......

import numpy as np 
import pandas as pd 
import string 
from scipy.spatial.distance import pdist, squareform 
# Computes the distance between m points using Euclidean distance (2-norm) 
# as the distance metric between the points. The points are arranged as m 
# n-dimensional row vectors in the matrix X. 

# Test data frame 
N = 12 # Nr of points 
col_ids = string.letters[:N] 
df = pd.DataFrame(
     np.random.randn(4203, 3*N+1), 
     columns=['Time']+['{}_{}'.format(letter, coord) for letter in col_ids for coord in list('xyz')]) 

# Drop time column for later use 
df_time = df['Time'] 
df = df.drop('Time',1) 

print df.shape 

# Use numpy.reshape to reshape the underlying data in the DataFrame 
df = pd.DataFrame(df.values.reshape(-1,3), columns=list('XYZ')) 
df["Time"] = np.repeat(np.array(df_time), N) 

print df.shape 

# Find the Euclidean distance (2-norm) 
N_lim = int(0.5*N*(N-1)) 
result_index = ['D{}'.format(coord) for coord in range(1,N_lim+1)] 
two_norm = df.groupby('Time')[["X", "Y", "Z"]].apply(lambda g: pd.Series(pdist(g), index=result_index)) 

print two_norm.shape 

它具有輸出(從三個打印語句)

(4203, 36) 
(50436, 4) 
(4203, 66) 

正如您所看到的,最終結果的形狀與其應該完全相同。但是在這兩組數據之間確實沒有什麼不同(只要我能說出來),禁止數字差異,這對數據幀的實際形狀應該沒有任何影響。

我錯過了什麼?

謝謝。


原始數據可以在這裏找到(在這篇文章的第一部分中使用的一個):https://www.dropbox.com/sh/80f8ue4ffa4067t/Pntl5-gUW4

應當注意的是。在dropbox中找到的csv文件是數據幀df_f_2_norm - 因此它不是原始數據,而是重新定型的版本(因此上面的第一行代碼不需要執行即可達到此狀態,因爲它已經執行)。

+0

ü可以通過Dropbox的分享在CSV/HDF您的數據(輸入數據)。什麼版本的熊貓/ numpy – Jeff

+0

原始數據可以在這裏找到:https://www.dropbox.com/sh/80f8ue4ffa4067t/Pntl5-gUW4 - 我的熊貓版本是0.12.0和numpy是1.7.1。 – Astrid

回答

1

如果您運行下面的代碼

df_f_2_norm.Time.value_counts() 

然後你就可以發現,並非所有的時間價值12行。

這裏是輸出:

1.333 492 
1.383 492 
1.317 492 
1.400 492 
1.467 492 
1.450 492 
1.483 492 
1.417 492 
1.500 492 
1.367 492 
1.350 492 
1.433 492 
1.533 480 
1.517 480 
1.550 468 
... 
4.800 12 
4.600 12 
4.750 12 
4.833 12 
4.667 12 
4.700 12 
4.650 12 
4.683 12 
4.633 12 
4.617 12 
4.817 12 
4.583 12 
4.733 12 
4.767 12 
4.783 12 
Length: 272, dtype: int64 

如果要組數據幀,每12行,您可以:

import pandas as pd 
from scipy.spatial.distance import pdist, squareform 

df_f_2_norm = pd.read_csv("astrid_data.csv") 
g = np.repeat(np.arange(df_f_2_norm.shape[0]//12), 12) 

N = 12 

N_lim = int(0.5*N*(N-1)) 
result_index = ['D{}'.format(tag) for tag in range(1,N_lim+1)] # Column labels 
two_norm = df_f_2_norm.groupby(g)[["X", "Y", "Z"]].apply(lambda g: pd.Series(pdist(g), index=result_index)) 
+0

歡呼你的回覆HYRY。我不明白的是爲什麼這條線路不工作df_f_2_norm [「Time」] = np.repeat(np.array(df_f_2_norm_time),N)#每個時間點的標記點數:12' - 整個點該行將創建每個時間戳的12個副本。但是出於某種原因,這不起作用? – Astrid