【问题标题】:pd.DataFrame is overwriting columns, instead of saving data to pd.DataFramepd.DataFrame 正在覆盖列,而不是将数据保存到 pd.DataFrame
【发布时间】:2019-10-24 17:28:20
【问题描述】:

在这里,我正在尝试创建一个数据帧来比较帧之间对象的位置:

Pcount = []
Pcountdb = []
framenumber = 0
frames_count = 0
frames_count = self.vdo.get(cv2.CAP_PROP_FRAME_COUNT)
df = pd.DataFrame(index=range(int(frames_count))) 
if len(outputs) > 0:
    for i in range(len(outputs):
        bbox_xyxy = outputs[:,:4]
        identities = outputs[:,-1]
        sx = outputs[:,0]
        sy = outputs[:,1]
        ex = outputs[:,2]
        ey = outputs[:,3]
        cx = ((sx + ex) /2)
        cy = ((sy + ey) /2)
        ct = (cx, cy)
        cx2 = (cx.tolist())
        cy2 = (cy.tolist())
        P = identities[i]
        df[str(P.astype(int))] = ""                              
        #creates new column with an id number obtained through deepsort

        df.at[int(framenumber), str(P.astype(int))] = [cx2[i], cy2[i]]  
        #the i function from a for loop is necessary for multiple objects in the same frame
        
        print(df)

        if not P in Pcountdb:
            global PcountT
            Pcountdb.append(P)
            PcountT = PcountT + 1

framenumber = framenumber + 1

已编辑:上面的脚本以占位符开头

df = pd.DataFrame... 为我的视频中的每个图像/帧创建一行数据帧

一旦我的对象检测器被 deepsort 循环遍历,就会创建 bbox_xyxy,并且 deepsort 已识别每个检测到的对象并将其识别为具有位置的对象。

然后,我分解 np.arrays 并计算这些对象的中心点,这样它们就可以被视为一个单独的点,而不是一个边界框矩形。

Pandas 接受我的输入并创建一个带有对象 id(在本例中为 1)、中心 x y 坐标的 DataFrame,并将它们放置在与每个帧对应的行中

接下来,我们打印数据框并查看结果

print(df) 返回:

                     1
Frames                
3       [614.5, 632.0]

                     1
Frames                
3                     
4       [610.5, 624.0]

                     1
Frames                
3                     
4                     
5       [603.0, 618.0]

                     1
Frames                
3                     
4                     
5                     
6       [574.0, 615.5]

                     1
Frames                
3                     
4                     
5                     
6                     
7       [564.0, 610.0]

                     1
Frames                
3                     
4                     
5                     
6                     
7                     
8       [559.0, 597.0]

DataFrame 仅跟踪每列的最新坐标集。如果我要生成两列,则只有每个对象的最后一次出现在我的数据框中(如上所示,一个对象,标识为 1)

我需要将输出保存到我​​的 pd.DataFrame = df,而不是被覆盖。

                     1
Frames                
3       [614.5, 632.0]
4       [610.5, 624.0]
5       [603.0, 618.0]
6       [574.0, 615.5]
7       [564.0, 610.0]
8       [559.0, 597.0]

所以我可以比较这些对象在帧之间的位置,给我一个对象计数,该计数对对象进行计数并将它们存储在 2 个数据库中,“UP”和“DOWN”

【问题讨论】:

  • 抱歉,有什么问题?
  • 你能清楚地说明你想要输出什么吗?
  • 抱歉,我希望将这些数据保存到我的 pandas.DataFrame = df 中,以便我可以在脚本中进一步访问它。
  • 为什么使用 .at。是否要将其存储在特定位置?
  • 如果有其他方法可以将我的坐标绘制到这些位置,请分享!

标签: python pandas numpy opencv tracking


【解决方案1】:

您的 DataFrame 只是添加最后一个原始数据,因为每次 for 循环运行时,您都会将列重置为 null。所以所有以前的值都被删除了。 通过查看您的代码,我可以看到,因为您的代码不需要在 for 循环中。

解决方案

Pcount = []
Pcountdb = []
framenumber = 0
frames_count = 0
frames_count = self.vdo.get(cv2.CAP_PROP_FRAME_COUNT)
df = pd.DataFrame(index=range(int(frames_count))) 
if len(outputs) > 0:
    bbox_xyxy = outputs[:,:4]
    identities = outputs[:,-1]
    sx = outputs[:,0]
    sy = outputs[:,1]
    ex = outputs[:,2]
    ey = outputs[:,3]
    cx = ((sx + ex) /2)
    cy = ((sy + ey) /2)
    ct = (cx, cy)
    cx2 = (cx.tolist())
    cy2 = (cy.tolist())
    P = identities[i]
    df[str(P.astype(int))] = ""
    for i in range(len(outputs):
        df.at[int(framenumber), str(P.astype(int))] = [cx2[i], cy2[i]]
        print(df)

希望这行得通。

【讨论】:

  • 感谢您的回复。我试过了,但不得不将 P=identities[i] 和 df[str(P.astype(int))] = "" 移动到 for i in range(因为 P 依赖于 i)。我正在寻找一种解决方法或另一种方法来将此数据框的数据合并到另一个。我试图使用 pd.concat 将此数据框加入此数据框的相同副本: df2 = pd.DataFrame(index=range(int(frames_count))) 我的结果是: df2 为对象创建列但没有t 附加坐标,所以我的数据框是空的
【解决方案2】:
for i in range(len(outputs)):
                    P = identities[i]

                    if not P in Pcountdb:
                        df[str(P.astype(int))] = ""
                        global PcountT
                        Pcountdb.append(P)
                        PcountT = PcountT + 1
                    else:
                        if P in Pcountdb:
                            df.at[int(framenumber), str(P.astype(int))] = [cx2[i], cy2[i]]


[222 rows x 1 columns]
                     1
 Frames                
 4       [610.5, 624.0]
 5       [603.0, 618.0]
 6       [574.0, 615.5]
 7       [564.0, 610.0]
 8       [559.0, 597.0]
 ...                ...
 226     [640.5, 518.5]
 227     [643.0, 525.0]
 228     [646.0, 529.5]
 229     [647.5, 529.5]
 230     [650.5, 531.5]

感谢@Adarsh 的回复,你是对的,我的列被覆盖了,因为我是从循环中创建它们的。

我选择了 df[str(P.astype(int))] = "" 行,其中创建了列,并在排他的情况下运行它。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-11
  • 2019-08-15
  • 1970-01-01
  • 2018-07-13
  • 1970-01-01
  • 2019-06-04
  • 1970-01-01
相关资源
最近更新 更多