我是Spark的初学者,我正在寻找解决方案。 我正在尝试根据每列包含的空值的数量以升序对数据框进行排序。
例如: 数据:
column1 Column2 Column3
a d h
b null null
null e i
null f h
null null k
c g l
排序后,数据框应为:
Column3 Colum2 Column1
我所能做的就是计算每一列的空值。
data.select([count(when(col(c).isNull(), c)).alias(c) for c in data.columns])
现在,我不知道如何继续。我希望你能帮助我。
答案 0 :(得分:0)
我的解决方案,可以根据需要工作:
#include <atlbase.h>
#include <atlcom.h>
#include <shobjidl_core.h>
#include <shlobj_core.h>
#include <exdispid.h>
// a COM class that handles DShellWindowsEvents
class WindowsEvents : public IDispatch
{
// poor man's COM object... we don't care, we're basically a static thing here
STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject)
{
if (IsEqualIID(riid, IID_IUnknown))
{
*ppvObject = static_cast<IUnknown*>(this);
return S_OK;
}
if (IsEqualIID(riid, IID_IDispatch))
{
*ppvObject = static_cast<IDispatch*>(this);
return S_OK;
}
*ppvObject = NULL;
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) AddRef() { return 1; }
STDMETHODIMP_(ULONG) Release() { return 1; }
// this is what's called by the Shell (BTW, on the same UI thread)
// there are only two events "WindowRegistered" (opened) and "WindowRevoked" (closed)
STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
// first parameter is window's registration cookie
int cookie = V_I4(&pDispParams->rgvarg[0]);
if (dispIdMember == DISPID_WINDOWREGISTERED) // needs exdispid.h
{
wprintf(L"Window registered, cookie:%u\n", cookie);
}
else if (dispIdMember == DISPID_WINDOWREVOKED)
{
wprintf(L"Window revoked, cookie:%u\n", cookie);
}
// currently the cookie is not super useful, it's supposed to be usable by FindWindowSW
CComVariant empty;
long hwnd;
CComPtr<IDispatch> window;
HRESULT hr = Windows->FindWindowSW(&pDispParams->rgvarg[0], &empty, 0, &hwnd, SWFO_COOKIEPASSED, &window);
// always returns S_FALSE... it does not seem to work
// so, you'll have to ask for all windows again...
return S_OK;
}
// the rest is left not implemented
STDMETHODIMP GetTypeInfoCount(UINT* pctinfo) { return E_NOTIMPL; }
STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) { return E_NOTIMPL; }
STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) { return E_NOTIMPL; }
public:
CComPtr<IShellWindows> Windows;
};
int main()
{
CoInitialize(NULL);
{
CComPtr<IShellWindows> windows;
if (SUCCEEDED(windows.CoCreateInstance(CLSID_ShellWindows)))
{
// dump current windows
long count = 0;
windows->get_Count(&count);
for (long i = 0; i < count; i++)
{
CComPtr<IDispatch> window;
if (SUCCEEDED(windows->Item(CComVariant(i), &window)))
{
// get the window handle
CComPtr<IWebBrowserApp> app;
if (SUCCEEDED(window->QueryInterface(&app)))
{
HWND hwnd = NULL;
app->get_HWND((SHANDLE_PTR*)&hwnd);
wprintf(L"HWND[%i]:%p\n", i, hwnd);
}
}
}
// now wait for windows to open
// get the DShellWindowsEvents dispinterface for events
CComPtr<IConnectionPointContainer> cpc;
if (SUCCEEDED(windows.QueryInterface(&cpc)))
{
// https://docs.microsoft.com/en-us/windows/win32/shell/dshellwindowsevents
CComPtr<IConnectionPoint> cp;
if (SUCCEEDED(cpc->FindConnectionPoint(DIID_DShellWindowsEvents, &cp)))
{
WindowsEvents events;
events.Windows = windows;
DWORD cookie = 0;
// hook events
if (SUCCEEDED(cp->Advise(&events, &cookie)))
{
// pump COM messages to make sure events arrive
do
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} while (TRUE);
// normally we should get here if someone sends a PostQuitMessage(0) to the current thread
// but this is a console sample...
// unhook events
cp->Unadvise(cookie);
}
}
}
}
}
CoUninitialize();
return 0;
}