计算numpy中许多轨迹的平均轨迹

时间:2017-01-19 14:54:00

标签: python pandas numpy

我有很多轨迹文件,每个文件都有3列,表示位置xyz。我想计算平均位置,基本上定义如下 - 对于给定的行,从所有轨迹计算x的平均值。同样,yz尺寸也是如此。

所以,我正在迭代这些数组,并将所有x存储在一个列表中,类似地存储在yz中。后来我正在计算平均值。请参见下面的示例代码 -

import numpy as np
import pandas as pd

file_list = ['test1_1', 'test2_4', 'test3_1', 'test4_3', 'test1_3']
position_data_list = []
for f in file_list:
    position_data = pd.read_csv(f) 
    position_data_list.append(position_data.values)

position_x_list = []
position_y_list = []
position_z_list = []
for position_data in position_data_list:
    px = _position_data[:, 0]
    py = _position_data[:, 1]
    pz = _position_data[:, 2]
    position_x_list.append(px)
    position_y_list.append(py)
    position_z_list.append(pz)

position_x_list = np.array(position_x_list).T
position_y_list = np.array(position_y_list).T
position_z_list = np.array(position_z_list).T

position_x_mean = np.mean(position_x_list, axis=1)
position_y_mean = np.mean(position_y_list, axis=1)
position_z_mean = np.mean(position_z_list, axis=1)

还有更好的方法吗?

让我解释一下上面的代码。假设filesfile_1file_2file_3。每个文件都有xyz列,其中每行的时间戳为t1t2t3,{{ 1}}和t4。平均轨迹应包含t5t1的所有行,其中t5表示来自文件x1的{​​{1}},x和{行file_1的{​​1}}。等等...

3 个答案:

答案 0 :(得分:2)

实际上,大熊猫非常强大,除了阅读数据外,还可以做更多的事情。您已经将数据读入pandas数据帧,然后您可以连接数据帧并使用pandas计算每列的平均值。如果您尝试计算每个时间戳的平均值,可以尝试使用groupby函数。假设时间戳的列名是“ts”,请尝试以下操作:

import pandas as pd
file_list = ['test1_1', 'test2_4', 'test3_1', 'test4_3', 'test1_3']
df = pd.DataFrame()             # Create an empty dataframe
for file in file_list:
    df2 = pd.read_csv(file)     # Read data and store the results in df2
    df = pd.concat([df, df2])   # Concatenate your dataframes and store the results in df
print(df.groupby('ts').mean())  # Assuming 'ts' is the column of time stamp, print the results

输入:

file1: 

ts  x   y   z
t1  1   3   5
t2  2   4   6
t3  3   5   7
t4  4   6   8
t5  5   7   9

file2:

ts  x   y   z
t1  1   4   5
t2  2   6   6
t3  3   8   7
t4  4   10  8
t5  5   12  9

输出:

      x    y    z
ts               
t1  1.0  3.5  5.0
t2  2.0  5.0  6.0
t3  3.0  6.5  7.0
t4  4.0  8.0  8.0
t5  5.0  9.5  9.0

答案 1 :(得分:0)

因此,您希望对帧上的每个坐标进行平均,并且可以将所有帧作为内存中的数组。然后,您可以将所有轨迹作为单个阵列,其中一个维度表示帧,另一个维度表示移动元素(当前行),最后一个维度表示轴(当前列)。假设您的维度按顺序排列,那么您希望该数组的平均值超过第一维:您可以使用my_array.mean(axis=0)

我在测试系统上得到了相同的结果,其代码如下:

file_list = glob('csv_frames/*')

position_data_list = []
for frame in file_list:
    position_data_list.append(numpy.loadtxt(frame, delimiter=','))
# Convert the list of arrays into a 3D array
position_data_list = numpy.asarray(position_data_list)

# Actually calculate the averaged coordinates
position_mean = position_data_list.mean(axis=0)

# If realy you need each axis on its own array
position_x_mean = position_mean[:, 0]
position_y_mean = position_mean[:, 1]
position_z_mean = position_mean[:, 2]

在我的示例中,我使用numpy.loadtxt来读取CSV文件。根据您的文件,您可能需要调整参数。您还可以使用pandas读取文件,并使用as_matrix方法从DataFrame中提取数组。

我使用MDAnalysis

从分子动力学模拟轨迹构建了我的测试帧
import numpy
import MDAnalysis as mda
from MDAnalysisTests.datafiles import TPR, XTC

# Read the trajectory
u = mda.Universe(TPR, XTC)
# Write each frame in a separate CSV file
for ts in u.trajectory:
    numpy.savetxt('csv_frames/frame_{}.csv'.format(ts.frame),
                  u.atoms.positions, delimiter=',')

答案 2 :(得分:0)

import pandas as pd
import glob, os


file_list = ['test1_1', 'test2_4', 'test3_1', 'test4_3', 'test1_3']
position_data_list =  pd.DataFrame()
for f in file_list:
    position_data_list =position_data_list.append(pd.read_csv(tfile))

position_data_list.columns=['X','Y','Z']
print position_data_list["Y"].mean()
print position_data_list["X"].mean()
print position_data_list["Z"].mean()

输入

5.742023, 0.193241, 2.874091
8.742023, 0.35, 2.78
23, 0.55, 2.89
7.742023, 0.65, .8274091

输出

0.516666666667
13.1613486667
2.16580303333