def replace_dataframe(
        self,
        dataframe_name,
        df,
        already_sorted=False,
        recalculate_last_time_indexes=True,
    ):
        """Replace the internal dataframe of an EntitySet table, keeping Woodwork typing information the same.
        Optionally makes sure that data is sorted, that reference indexes to other dataframes are consistent,
        and that last_time_indexes are updated to reflect the new data. If an index was created for the original
        dataframe and is not present on the new dataframe, an index column of the same name will be added to the
        new dataframe.
        """
        if not isinstance(df, type(self[dataframe_name])):
            raise TypeError("Incorrect DataFrame type used")

        # If the original DataFrame has a last time index column and the new one doesnt
        # remove the column and the reference to last time index from that dataframe
        last_time_index_column = self[dataframe_name].ww.metadata.get("last_time_index")
        if (
            last_time_index_column is not None
            and last_time_index_column not in df.columns
        ):
            self[dataframe_name].ww.pop(last_time_index_column)
            del self[dataframe_name].ww.metadata["last_time_index"]

        # If the original DataFrame had an index created via make_index,
        # we may need to remake the index if it's not in the new DataFrame
        created_index = self[dataframe_name].ww.metadata.get("created_index")
        if created_index is not None and created_index not in df.columns:
            df = _create_index(df, created_index)

        old_column_names = list(self[dataframe_name].columns)
        if len(df.columns) != len(old_column_names):
            raise ValueError(
                "New dataframe contains {} columns, expecting {}".format(
                    len(df.columns),
                    len(old_column_names),
                ),
            )
        for col_name in old_column_names:
            if col_name not in df.columns:
                raise ValueError(
                    "New dataframe is missing new {} column".format(col_name),
                )

        if df.ww.schema is not None:
            warnings.warn(
                "Woodwork typing information on new dataframe will be replaced "
                f"with existing typing information from {dataframe_name}",
            )

        df.ww.init(
            schema=self[dataframe_name].ww._schema,
            already_sorted=already_sorted,
        )
        # Make sure column ordering matches original ordering
        df = df.ww[old_column_names]

        df = self._normalize_values(df)

        self.dataframe_dict[dataframe_name] = df

        if self[dataframe_name].ww.time_index is not None:
            self._check_uniform_time_index(self[dataframe_name])

        df_metadata = self[dataframe_name].ww.metadata
        self.set_secondary_time_index(
            dataframe_name,
            df_metadata.get("secondary_time_index"),
        )
        if recalculate_last_time_indexes and last_time_index_column is not None:
            self.add_last_time_indexes(updated_dataframes=[dataframe_name])
        self.reset_data_description()
        self._add_references_to_metadata(df)
Replace the internal dataframe of an EntitySet table, keeping Woodwork typing information the same.
        Optionally makes sure that data is sorted, that reference indexes to other dataframes are consistent,
        and that last_time_indexes are updated to reflect the new data. If an index was created for the original
        dataframe and is not present on the new dataframe, an index column of the same name will be added to the
        new dataframe.
        
featuretools/entityset/entityset.py