我有一组4203x37
的CSV数据,我将其重新整形为50436x4
,以便找到每组时间步记录的12组3D点之间的欧几里德距离。这对我的实际数据不起作用,但奇怪的是,当我使用随机数重新创建数据时,代码如下......
以下是我的实际数据的代码,这是无效的代码。
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
的形状,即12个点的66欧几里德距离,每个时间戳有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))
然后我们得到print two_norm.shape
的形状((8307846,)
) - 我不太明白这里发生了什么,但看起来它甚至没有将所有结果叠加在一起。
虽然它变得更好,因为以下代码在行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 :(得分: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))