Pandas合并/连接数据框

0 投票
1 回答
753 浏览
提问于 2025-04-18 07:48

我不太确定这是不是指合并或者连接。

我有一个数据表,里面有两列,分别是 ['times','spots'],我们叫它数据表A。还有另一个数据表,列名也差不多,也是 ['times','spots'],我们叫它数据表B。

我想把数据表A改一下,让它在A的时间点上,插入数据表B的值。这样,数据表A就会多出一列,叫做spots_B。

1 个回答

2

好吧,我要大胆一点,给你展示一下怎么用后缀合并数据:

# First import our libraries
>>> import pandas as pd
>>> import numpy as np
# Then create our dataframes
>>> df_A = pd.DataFrame(np.random.rand(3,2),columns=['times','spots'])
>>> df_B = pd.DataFrame(np.random.rand(3,2),columns=['times','spots'])
# Set default values
>>> df_A['times'] = [1,2,3]
>>> df_B['times'] = [1,2,3]
>>> df_A['spots'] = [44,55,66]
>>> df_B['spots'] = [77,88,99]
# Here is what both dataframes contain
>>> df_A
   times  spots
0      1     44
1      2     55
2      3     66
>>> df_B
   times  spots
0      1     77
1      2     88
2      3     99
# Now the merge -- note: this does not affect the first dataframe in place.
#                        It will create a new dataframe. You can overwrite the 
#                        first if you set the result to df_A instead of df_merged.
# Note the use of the keyword, suffixes. In the event that the same column names exist
#  in both dataframes (that aren't being merged on) Pandas will need to differentiate
#  between them. By default same column names will result in a '_x' will be appended to
#  the left dataframe column name, and a '_y' to the right dataframe column name
#  [order is set by the first two arguments in the merge function]. 
#  The suffixes keyword allows the user to override this behaviour with their
#  own version of '_x' and '_y'.
>>> df_merged = pd.merge(df_A,df_B,how='inner',on=['times'],suffixes=['_A','_B'])
>>> df_merged
   times  spots_A  spots_B
0      1       44       77
1      2       55       88
2      3       66       99

从你的问题来看,你似乎不想修改第一个数据框中“spots”这一列的名字。其实可以用类似的方法来实现,只不过这次用 suffixes=['','_B'],这样就把左边数据框的列后缀设置为空,也就是说它的名字保持不变:

>>> df_merged = pd.merge(df_A,df_B,how='inner',on=['times'],suffixes=['','_B'])
>>> df_merged
   times  spots  spots_B
0      1     44       77
1      2     55       88
2      3     66       99

好了!希望这对你有帮助。如果我理解错了,你其实是想要A和B之间的插值,告诉我,我会修改这个回答。

* 编辑 1 *

考虑到你最后的评论,我认为你想要实现的是这个。下面我会告诉你怎么在合并时使用后缀,然后用“时间”插值法填充“spots_B”中的空值。

# Start by creating out datetimes to set for the times column
>>> times_A = []
>>> times_B = []
>>> for i in range(1,4):
...   times_A.append(datetime.datetime(year=2011,month=5,day=i))
...
>>> for i in range(1,6,2):
...   times_B.append(datetime.datetime(year=2011,month=5,day=i))
...
# times_A: May 1st, 2011 - May 3rd, 2011
>>> times_A
[datetime.datetime(2011, 5, 1, 0, 0), datetime.datetime(2011, 5, 2, 0, 0), datetime.datetime(2011, 5, 3, 0, 0)]
# times_B: May 1st 2011, May 3rd 2011, May 5th 2011
>>> times_B
[datetime.datetime(2011, 5, 1, 0, 0), datetime.datetime(2011, 5, 3, 0, 0), datetime.datetime(2011, 5, 5, 0, 0)]
# So now times_B is missing May 2nd, and has an extra time, May 5th.
>>> df_A['times'] = times_A
>>> df_B['times'] = times_B
>>> df_A['spots'] = [44,55,66]
>>> df_B['spots'] = [44,66,88]
>>> df_A
                times  spots
0 2011-05-01 00:00:00     44
1 2011-05-02 00:00:00     55
2 2011-05-03 00:00:00     66
>>> df_B
                times  spots
0 2011-05-01 00:00:00     44
1 2011-05-03 00:00:00     66
2 2011-05-05 00:00:00     88

# Now it appears you only care about the times in df_A - so
#   left merge df_A with df_B (include all times from df_A and  
#   try to merge with df_B or NaN). Below the date May 5th was dropped.
>>> df_merged = pd.merge(df_A,df_B,how='left',on=['times'],suffixes=['','_B'])
>>> df_merged
                times  spots  spots_B
0 2011-05-01 00:00:00     44       44
1 2011-05-02 00:00:00     55      NaN
2 2011-05-03 00:00:00     66       66

# Here is the important part:
# Since it appears that your data is going to be a time series
#   you will need to set your dataframe index to be the times column.
>>> df_merged = df_merged.set_index(['times'])
>>> df_merged
            spots  spots_B
times
2011-05-01     44       44
2011-05-02     55      NaN
2011-05-03     66       66

# With the times as index we can use the appropriate
#   interpolation method for best results
>>> df_merged['spots_B'] = df_merged['spots_B'].interpolate(method='time')
>>> df_merged
            spots  spots_B
times
2011-05-01     44       44
2011-05-02     55       55
2011-05-03     66       66

注意:interpolate()Series 上的默认行为是认为每一行之间的距离是相等的。如果你的时间数据不是均匀间隔的,你需要用时间序列索引重新索引你的数据框。当索引是时间序列时,你就可以在 interpolate() 函数中使用 method='time' 参数。

注意2:提问时尽量提供更多细节,这样回答你的人才能更好地理解你的问题。

撰写回答