gpt4 book ai didi

python - 当函数应用于行时, Pandas 的 .groupby 函数出现奇怪的问题

转载 作者:太空宇宙 更新时间:2023-11-04 06:07:47 25 4
gpt4 key购买 nike

我有一组 CSV 数据,它是 4203x37,我将其整形为 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))

然后我们得到 (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 - 因此它不是原始数据,而是重新整形的版本(所以第一行代码在上面,不需要执行到这个状态,因为它已经被执行了)。

最佳答案

如果你运行下面的代码

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))

关于python - 当函数应用于行时, Pandas 的 .groupby 函数出现奇怪的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20983419/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com