-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Requesting process_dataframe()
#167
Comments
Is the idea behind it, that the processing function has also access to the labels in the dataframe, or just that you can use the newly segmented dataframe with the column of the original labels as ground truth afterwards. The later, could most likely also be solved by a function that takes as input the original dataframe and the new index, and then assigns the original labels to the new segments. The first part was handled so far by the special processing args But I agree, that it might be more elegant to just add something like |
Processing the original labels was not something I had in my mind, so far, so the "external" function might be sufficient. |
Having access to the labels is also not that easy, as usually we provide a processing function, that works also for Which means the new |
|
Great, @maxschmitt would you be able to try to work on it? |
sounds reasonable ;) challenge accepted |
Thinking about it, would it actually be necessary to have My idea would be to have For |
I am not sure if I got it correct, but: The solution from #25 will not work as we would need the Only The idea of having |
Yes and no. If your starting point is a filewise index, you can use the special argument import audb
import audinterface
import auvad
# Prepare data
media = [
"wav/03a01Fa.wav",
"wav/03a01Nc.wav",
"wav/16b10Wb.wav",
]
db = audb.load(
"emodb",
version="1.4.1",
media=media,
full_path=False,
verbose=False,
)
df = db.get("emotion")
def access_label(signal, sampling_rate, file, df, label="emotion"):
return df.loc[file, label]
vad = auvad.Vad(max_turn_length=1)
interface = audinterface.Feature(
"emotion",
process_func=access_label,
process_func_args={"df": df},
segment=vad,
)
df_segmented = interface.process_index(db.files, root=db.root)
print(df_segmented) which returns
But you are right, if the starting dataframe contains already a segmented index, then we cannot handle it with the current solution. There you would need to first run the VAD and with the result create a new dataframe using the index returned by the VAD and assign the label accordingly. Afterwards, you can then use that dataframe together with At the moment, I'm not sure how easy/complicated it will be to change |
One straightforward fix for supporting also segmented indices would be to introduce |
But wouldn't the access to the labels be very inefficient, especially for large tables, as we need to get the labels for each row separately? My (current) idea is to add a method audinterface/audinterface/core/segment.py Line 501 in bdb078c
If I am not completely wrong, this would result in only a minor change (the new The drawback of this method is, of course, that we do not have this new method for the |
I also see the point in adding a But I'm not so sure if we could add it only to |
To be honest, I usually do not feel too comfortable when mixing two independent (segmentation, feature extraction) steps into a single function/method, because it makes the package more complex and less transparent. Generally, when doing segmentation and feature extraction, there are two cases:
At the moment, only 1. is supported but it might also be relevant to have 2, which requires using/calling I implemented a first version of Please check and we can see if it makes sense and if we should also have it in Test: import audb
import audinterface
import numpy as np
import os
import pandas as pd
def rms(signal, sampling_rate):
return 20 * np.log10(np.sqrt(np.mean(signal ** 2)))
def segment(signal, sampling_rate):
duration = signal.shape[-1] / sampling_rate
chunk_len = 0.7
chunks = []
for i in range(int(duration // chunk_len) + 1):
chunks.append((i * chunk_len,
np.min([(i+1) * chunk_len, duration])))
index = pd.MultiIndex.from_tuples(
[
(
pd.Timedelta(start, unit="s"),
pd.Timedelta(end, unit="s"),
)
for start, end in chunks
],
names=["start", "end"],
)
return index
media = [
"wav/03a01Fa.wav",
"wav/03a01Nc.wav",
"wav/16b10Wb.wav",
]
db = audb.load(
"emodb",
version="1.3.0",
media=media,
verbose=False,
)
files = list(db.files)
folder = os.path.dirname(files[0])
index = db["emotion"].index
# Compute RMS
interface = audinterface.Process(process_func=rms)
table_series = interface.process_index(index)
print(table_series)
# Segmentation with Series
seg_interface = audinterface.Segment(process_func=segment)
print(seg_interface.process_table(table_series))
# Segmentation with Dataframe
table_df = pd.DataFrame(np.concatenate((table_series.values.reshape(-1, 1),
table_series.values.reshape(-1, 1) * 2),
axis=-1),
table_series.index, columns=["RMS", "RMSx2"])
print(seg_interface.process_table(table_df)) |
Problem
Currently, it is not possible to apply a processing function of
audinterface.Process
oraudinterface.Feature
to aDataFrame
object.Such a method would be meaningful, as
process_index()
cannot be efficiently used when aSegment
object is passed assegment
argument, because labels need to be carried to the resulting dataframe (the resulting index after segmentation has typically additional rows).Solution
A new method
process_dataframe()
could solve this.process_index()
, but all labels are kept and attached to the output.@hagenw
The text was updated successfully, but these errors were encountered: